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

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

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.10.0)")
public class SharingRegistryService {

  public interface Iface extends org.apache.airavata.base.api.BaseAPI.Iface {

    /**
     * <p>API method to create a new domain</p>
     * 
     * @param domain
     */
    public java.lang.String createDomain(org.apache.airavata.sharing.registry.models.Domain domain) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException;

    /**
     * <p>API method to update a domain</p>
     * 
     * @param domain
     */
    public boolean updateDomain(org.apache.airavata.sharing.registry.models.Domain domain) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check Domain Exists</p>
     * 
     * @param domainId
     */
    public boolean isDomainExists(java.lang.String domainId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to delete domain</p>
     * 
     * @param domainId
     */
    public boolean deleteDomain(java.lang.String domainId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to retrieve a domain</p>
     * 
     * @param domainId
     */
    public org.apache.airavata.sharing.registry.models.Domain getDomain(java.lang.String domainId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get all domain.</p>
     * 
     * @param offset
     * @param limit
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.Domain> getDomains(int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to register a user in the system</p>
     * 
     * @param user
     */
    public java.lang.String createUser(org.apache.airavata.sharing.registry.models.User user) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException;

    /**
     * <p>API method to update existing user</p>
     * 
     * @param user
     */
    public boolean updatedUser(org.apache.airavata.sharing.registry.models.User user) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check User Exists</p>
     * 
     * @param domainId
     * @param userId
     */
    public boolean isUserExists(java.lang.String domainId, java.lang.String userId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to delete user</p>
     * 
     * @param domainId
     * @param userId
     */
    public boolean deleteUser(java.lang.String domainId, java.lang.String userId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get a user</p>
     * 
     * @param domainId
     * @param userId
     */
    public org.apache.airavata.sharing.registry.models.User getUser(java.lang.String domainId, java.lang.String userId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get a list of users in a specific domain.</p>
     * <li>domainId : Domain id</li>
     * <li>offset : Starting result number</li>
     * <li>limit : Number of max results to be sent</li>
     * 
     * @param domainId
     * @param offset
     * @param limit
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.User> getUsers(java.lang.String domainId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to create a new group</p>
     * 
     * @param group
     */
    public java.lang.String createGroup(org.apache.airavata.sharing.registry.models.UserGroup group) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to update a group</p>
     * 
     * @param group
     */
    public boolean updateGroup(org.apache.airavata.sharing.registry.models.UserGroup group) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check Group Exists</p>
     * 
     * @param domainId
     * @param groupId
     */
    public boolean isGroupExists(java.lang.String domainId, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to delete a group</p>
     * 
     * @param domainId
     * @param groupId
     */
    public boolean deleteGroup(java.lang.String domainId, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get a group</p>
     * 
     * @param domainId
     * @param groupId
     */
    public org.apache.airavata.sharing.registry.models.UserGroup getGroup(java.lang.String domainId, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get groups in a domainId.</p>
     * 
     * @param domainId
     * @param offset
     * @param limit
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getGroups(java.lang.String domainId, int offset, int limit) throws org.apache.thrift.TException;

    /**
     * <p>API method to add list of users to a group</p>
     * 
     * @param domainId
     * @param userIds
     * @param groupId
     */
    public boolean addUsersToGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to remove users from a group</p>
     * 
     * @param domainId
     * @param userIds
     * @param groupId
     */
    public boolean removeUsersFromGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to transfer group ownership</p>
     * 
     * @param domainId
     * @param groupId
     * @param newOwnerId
     */
    public boolean transferGroupOwnership(java.lang.String domainId, java.lang.String groupId, java.lang.String newOwnerId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to add Admin for a group</p>
     * 
     * @param domainId
     * @param groupId
     * @param adminIds
     */
    public boolean addGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to remove Admin for a group</p>
     * 
     * @param domainId
     * @param groupId
     * @param adminIds
     */
    public boolean removeGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check whether the user has Admin access for the group</p>
     * 
     * @param domainId
     * @param groupId
     * @param adminId
     */
    public boolean hasAdminAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String adminId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check whether the user has Admin access for the group</p>
     * 
     * @param domainId
     * @param groupId
     * @param ownerId
     */
    public boolean hasOwnerAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String ownerId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get list of child users in a group. Only the direct members will be returned.</p>
     * 
     * @param domainId
     * @param groupId
     * @param offset
     * @param limit
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.User> getGroupMembersOfTypeUser(java.lang.String domainId, java.lang.String groupId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get list of child groups in a group. Only the direct members will be returned.</p>
     * 
     * @param domainId
     * @param groupId
     * @param offset
     * @param limit
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getGroupMembersOfTypeGroup(java.lang.String domainId, java.lang.String groupId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to add a child group to a parent group.</p>
     * 
     * @param domainId
     * @param childIds
     * @param groupId
     */
    public boolean addChildGroupsToParentGroup(java.lang.String domainId, java.util.List<java.lang.String> childIds, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to remove a child group from parent group.</p>
     * 
     * @param domainId
     * @param childId
     * @param groupId
     */
    public boolean removeChildGroupFromParentGroup(java.lang.String domainId, java.lang.String childId, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getAllMemberGroupsForUser(java.lang.String domainId, java.lang.String userId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to create a new entity type</p>
     * 
     * @param entityType
     */
    public java.lang.String createEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException;

    /**
     * <p>API method to update entity type</p>
     * 
     * @param entityType
     */
    public boolean updateEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check EntityType Exists</p>
     * 
     * @param domainId
     * @param entityTypeId
     */
    public boolean isEntityTypeExists(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to delete entity type</p>
     * 
     * @param domainId
     * @param entityTypeId
     */
    public boolean deleteEntityType(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get an entity type</p>
     * 
     * @param domainId
     * @param entityTypeId
     */
    public org.apache.airavata.sharing.registry.models.EntityType getEntityType(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get entity types in a domainId.</p>
     * 
     * @param domainId
     * @param offset
     * @param limit
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.EntityType> getEntityTypes(java.lang.String domainId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to register new entity</p>
     * 
     * @param entity
     */
    public java.lang.String createEntity(org.apache.airavata.sharing.registry.models.Entity entity) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to update entity</p>
     * 
     * @param entity
     */
    public boolean updateEntity(org.apache.airavata.sharing.registry.models.Entity entity) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check Entity Exists</p>
     * 
     * @param domainId
     * @param entityId
     */
    public boolean isEntityExists(java.lang.String domainId, java.lang.String entityId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to delete entity</p>
     * 
     * @param domainId
     * @param entityId
     */
    public boolean deleteEntity(java.lang.String domainId, java.lang.String entityId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get entity</p>
     * 
     * @param domainId
     * @param entityId
     */
    public org.apache.airavata.sharing.registry.models.Entity getEntity(java.lang.String domainId, java.lang.String entityId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to search entities</p>
     * 
     * @param domainId
     * @param userId
     * @param filters
     * @param offset
     * @param limit
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.Entity> searchEntities(java.lang.String domainId, java.lang.String userId, java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get a list of shared users given the entity id</p>
     * 
     * @param domainId
     * @param entityId
     * @param permissionTypeId
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.User> getListOfSharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get a list of shared users given the entity id where the sharing type is directly applied</p>
     * 
     * @param domainId
     * @param entityId
     * @param permissionTypeId
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.User> getListOfDirectlySharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get a list of shared groups given the entity id</p>
     * 
     * @param domainId
     * @param entityId
     * @param permissionTypeId
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getListOfSharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get a list of directly shared groups given the entity id where the sharing type is directly applied</p>
     * 
     * @param domainId
     * @param entityId
     * @param permissionTypeId
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getListOfDirectlySharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to create permission type</p>
     * 
     * @param permissionType
     */
    public java.lang.String createPermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException;

    /**
     * <p>API method to update permission type</p>
     * 
     * @param permissionType
     */
    public boolean updatePermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check Permission Exists</p>
     * 
     * @param dimainId
     * @param permissionId
     */
    public boolean isPermissionExists(java.lang.String dimainId, java.lang.String permissionId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to delete permission type</p>
     * 
     * @param domainId
     * @param permissionTypeId
     */
    public boolean deletePermissionType(java.lang.String domainId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get permission type</p>
     * 
     * @param domainId
     * @param permissionTypeId
     */
    public org.apache.airavata.sharing.registry.models.PermissionType getPermissionType(java.lang.String domainId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to get list of permission types in a given domainId.</p>
     * 
     * @param domainId
     * @param offset
     * @param limit
     */
    public java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> getPermissionTypes(java.lang.String domainId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to share an entity with users</p>
     * 
     * @param domainId
     * @param entityId
     * @param userList
     * @param permissionTypeId
     * @param cascadePermission
     */
    public boolean shareEntityWithUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, boolean cascadePermission) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to revoke sharing from a list of users</p>
     * 
     * @param domainId
     * @param entityId
     * @param userList
     * @param permissionTypeId
     */
    public boolean revokeEntitySharingFromUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to share an entity with list of groups</p>
     * 
     * @param domainId
     * @param entityId
     * @param groupList
     * @param permissionTypeId
     * @param cascadePermission
     */
    public boolean shareEntityWithGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, boolean cascadePermission) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to revoke sharing from list of users</p>
     * 
     * @param domainId
     * @param entityId
     * @param groupList
     * @param permissionTypeId
     */
    public boolean revokeEntitySharingFromGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

    /**
     * <p>API method to check whether a user has access to a specific entity</p>
     * 
     * @param domainId
     * @param userId
     * @param entityId
     * @param permissionTypeId
     */
    public boolean userHasAccess(java.lang.String domainId, java.lang.String userId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException;

  }

  public interface AsyncIface extends org.apache.airavata.base.api.BaseAPI .AsyncIface {

    public void createDomain(org.apache.airavata.sharing.registry.models.Domain domain, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void updateDomain(org.apache.airavata.sharing.registry.models.Domain domain, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void isDomainExists(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void deleteDomain(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getDomain(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Domain> resultHandler) throws org.apache.thrift.TException;

    public void getDomains(int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Domain>> resultHandler) throws org.apache.thrift.TException;

    public void createUser(org.apache.airavata.sharing.registry.models.User user, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void updatedUser(org.apache.airavata.sharing.registry.models.User user, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void isUserExists(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void deleteUser(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getUser(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.User> resultHandler) throws org.apache.thrift.TException;

    public void getUsers(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException;

    public void createGroup(org.apache.airavata.sharing.registry.models.UserGroup group, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void updateGroup(org.apache.airavata.sharing.registry.models.UserGroup group, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void isGroupExists(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void deleteGroup(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getGroup(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.UserGroup> resultHandler) throws org.apache.thrift.TException;

    public void getGroups(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException;

    public void addUsersToGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void removeUsersFromGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void transferGroupOwnership(java.lang.String domainId, java.lang.String groupId, java.lang.String newOwnerId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void addGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void removeGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void hasAdminAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String adminId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void hasOwnerAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String ownerId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getGroupMembersOfTypeUser(java.lang.String domainId, java.lang.String groupId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException;

    public void getGroupMembersOfTypeGroup(java.lang.String domainId, java.lang.String groupId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException;

    public void addChildGroupsToParentGroup(java.lang.String domainId, java.util.List<java.lang.String> childIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void removeChildGroupFromParentGroup(java.lang.String domainId, java.lang.String childId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getAllMemberGroupsForUser(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException;

    public void createEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void updateEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void isEntityTypeExists(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void deleteEntityType(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getEntityType(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.EntityType> resultHandler) throws org.apache.thrift.TException;

    public void getEntityTypes(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.EntityType>> resultHandler) throws org.apache.thrift.TException;

    public void createEntity(org.apache.airavata.sharing.registry.models.Entity entity, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void updateEntity(org.apache.airavata.sharing.registry.models.Entity entity, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void isEntityExists(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void deleteEntity(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getEntity(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Entity> resultHandler) throws org.apache.thrift.TException;

    public void searchEntities(java.lang.String domainId, java.lang.String userId, java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Entity>> resultHandler) throws org.apache.thrift.TException;

    public void getListOfSharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException;

    public void getListOfDirectlySharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException;

    public void getListOfSharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException;

    public void getListOfDirectlySharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException;

    public void createPermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException;

    public void updatePermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void isPermissionExists(java.lang.String dimainId, java.lang.String permissionId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void deletePermissionType(java.lang.String domainId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void getPermissionType(java.lang.String domainId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.PermissionType> resultHandler) throws org.apache.thrift.TException;

    public void getPermissionTypes(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>> resultHandler) throws org.apache.thrift.TException;

    public void shareEntityWithUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, boolean cascadePermission, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void revokeEntitySharingFromUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void shareEntityWithGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, boolean cascadePermission, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void revokeEntitySharingFromGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

    public void userHasAccess(java.lang.String domainId, java.lang.String userId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException;

  }

  public static class Client extends org.apache.airavata.base.api.BaseAPI.Client implements Iface {
    public static class Factory implements org.apache.thrift.TServiceClientFactory<Client> {
      public Factory() {}
      public Client getClient(org.apache.thrift.protocol.TProtocol prot) {
        return new Client(prot);
      }
      public Client getClient(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
        return new Client(iprot, oprot);
      }
    }

    public Client(org.apache.thrift.protocol.TProtocol prot)
    {
      super(prot, prot);
    }

    public Client(org.apache.thrift.protocol.TProtocol iprot, org.apache.thrift.protocol.TProtocol oprot) {
      super(iprot, oprot);
    }

    public java.lang.String createDomain(org.apache.airavata.sharing.registry.models.Domain domain) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException
    {
      send_createDomain(domain);
      return recv_createDomain();
    }

    public void send_createDomain(org.apache.airavata.sharing.registry.models.Domain domain) throws org.apache.thrift.TException
    {
      createDomain_args args = new createDomain_args();
      args.setDomain(domain);
      sendBase("createDomain", args);
    }

    public java.lang.String recv_createDomain() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException
    {
      createDomain_result result = new createDomain_result();
      receiveBase(result, "createDomain");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      if (result.dee != null) {
        throw result.dee;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createDomain failed: unknown result");
    }

    public boolean updateDomain(org.apache.airavata.sharing.registry.models.Domain domain) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_updateDomain(domain);
      return recv_updateDomain();
    }

    public void send_updateDomain(org.apache.airavata.sharing.registry.models.Domain domain) throws org.apache.thrift.TException
    {
      updateDomain_args args = new updateDomain_args();
      args.setDomain(domain);
      sendBase("updateDomain", args);
    }

    public boolean recv_updateDomain() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      updateDomain_result result = new updateDomain_result();
      receiveBase(result, "updateDomain");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateDomain failed: unknown result");
    }

    public boolean isDomainExists(java.lang.String domainId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_isDomainExists(domainId);
      return recv_isDomainExists();
    }

    public void send_isDomainExists(java.lang.String domainId) throws org.apache.thrift.TException
    {
      isDomainExists_args args = new isDomainExists_args();
      args.setDomainId(domainId);
      sendBase("isDomainExists", args);
    }

    public boolean recv_isDomainExists() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      isDomainExists_result result = new isDomainExists_result();
      receiveBase(result, "isDomainExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isDomainExists failed: unknown result");
    }

    public boolean deleteDomain(java.lang.String domainId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_deleteDomain(domainId);
      return recv_deleteDomain();
    }

    public void send_deleteDomain(java.lang.String domainId) throws org.apache.thrift.TException
    {
      deleteDomain_args args = new deleteDomain_args();
      args.setDomainId(domainId);
      sendBase("deleteDomain", args);
    }

    public boolean recv_deleteDomain() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      deleteDomain_result result = new deleteDomain_result();
      receiveBase(result, "deleteDomain");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteDomain failed: unknown result");
    }

    public org.apache.airavata.sharing.registry.models.Domain getDomain(java.lang.String domainId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getDomain(domainId);
      return recv_getDomain();
    }

    public void send_getDomain(java.lang.String domainId) throws org.apache.thrift.TException
    {
      getDomain_args args = new getDomain_args();
      args.setDomainId(domainId);
      sendBase("getDomain", args);
    }

    public org.apache.airavata.sharing.registry.models.Domain recv_getDomain() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getDomain_result result = new getDomain_result();
      receiveBase(result, "getDomain");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getDomain failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.Domain> getDomains(int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getDomains(offset, limit);
      return recv_getDomains();
    }

    public void send_getDomains(int offset, int limit) throws org.apache.thrift.TException
    {
      getDomains_args args = new getDomains_args();
      args.setOffset(offset);
      args.setLimit(limit);
      sendBase("getDomains", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.Domain> recv_getDomains() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getDomains_result result = new getDomains_result();
      receiveBase(result, "getDomains");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getDomains failed: unknown result");
    }

    public java.lang.String createUser(org.apache.airavata.sharing.registry.models.User user) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException
    {
      send_createUser(user);
      return recv_createUser();
    }

    public void send_createUser(org.apache.airavata.sharing.registry.models.User user) throws org.apache.thrift.TException
    {
      createUser_args args = new createUser_args();
      args.setUser(user);
      sendBase("createUser", args);
    }

    public java.lang.String recv_createUser() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException
    {
      createUser_result result = new createUser_result();
      receiveBase(result, "createUser");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      if (result.dee != null) {
        throw result.dee;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createUser failed: unknown result");
    }

    public boolean updatedUser(org.apache.airavata.sharing.registry.models.User user) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_updatedUser(user);
      return recv_updatedUser();
    }

    public void send_updatedUser(org.apache.airavata.sharing.registry.models.User user) throws org.apache.thrift.TException
    {
      updatedUser_args args = new updatedUser_args();
      args.setUser(user);
      sendBase("updatedUser", args);
    }

    public boolean recv_updatedUser() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      updatedUser_result result = new updatedUser_result();
      receiveBase(result, "updatedUser");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updatedUser failed: unknown result");
    }

    public boolean isUserExists(java.lang.String domainId, java.lang.String userId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_isUserExists(domainId, userId);
      return recv_isUserExists();
    }

    public void send_isUserExists(java.lang.String domainId, java.lang.String userId) throws org.apache.thrift.TException
    {
      isUserExists_args args = new isUserExists_args();
      args.setDomainId(domainId);
      args.setUserId(userId);
      sendBase("isUserExists", args);
    }

    public boolean recv_isUserExists() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      isUserExists_result result = new isUserExists_result();
      receiveBase(result, "isUserExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isUserExists failed: unknown result");
    }

    public boolean deleteUser(java.lang.String domainId, java.lang.String userId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_deleteUser(domainId, userId);
      return recv_deleteUser();
    }

    public void send_deleteUser(java.lang.String domainId, java.lang.String userId) throws org.apache.thrift.TException
    {
      deleteUser_args args = new deleteUser_args();
      args.setDomainId(domainId);
      args.setUserId(userId);
      sendBase("deleteUser", args);
    }

    public boolean recv_deleteUser() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      deleteUser_result result = new deleteUser_result();
      receiveBase(result, "deleteUser");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteUser failed: unknown result");
    }

    public org.apache.airavata.sharing.registry.models.User getUser(java.lang.String domainId, java.lang.String userId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getUser(domainId, userId);
      return recv_getUser();
    }

    public void send_getUser(java.lang.String domainId, java.lang.String userId) throws org.apache.thrift.TException
    {
      getUser_args args = new getUser_args();
      args.setDomainId(domainId);
      args.setUserId(userId);
      sendBase("getUser", args);
    }

    public org.apache.airavata.sharing.registry.models.User recv_getUser() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getUser_result result = new getUser_result();
      receiveBase(result, "getUser");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUser failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> getUsers(java.lang.String domainId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getUsers(domainId, offset, limit);
      return recv_getUsers();
    }

    public void send_getUsers(java.lang.String domainId, int offset, int limit) throws org.apache.thrift.TException
    {
      getUsers_args args = new getUsers_args();
      args.setDomainId(domainId);
      args.setOffset(offset);
      args.setLimit(limit);
      sendBase("getUsers", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> recv_getUsers() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getUsers_result result = new getUsers_result();
      receiveBase(result, "getUsers");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getUsers failed: unknown result");
    }

    public java.lang.String createGroup(org.apache.airavata.sharing.registry.models.UserGroup group) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_createGroup(group);
      return recv_createGroup();
    }

    public void send_createGroup(org.apache.airavata.sharing.registry.models.UserGroup group) throws org.apache.thrift.TException
    {
      createGroup_args args = new createGroup_args();
      args.setGroup(group);
      sendBase("createGroup", args);
    }

    public java.lang.String recv_createGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      createGroup_result result = new createGroup_result();
      receiveBase(result, "createGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createGroup failed: unknown result");
    }

    public boolean updateGroup(org.apache.airavata.sharing.registry.models.UserGroup group) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_updateGroup(group);
      return recv_updateGroup();
    }

    public void send_updateGroup(org.apache.airavata.sharing.registry.models.UserGroup group) throws org.apache.thrift.TException
    {
      updateGroup_args args = new updateGroup_args();
      args.setGroup(group);
      sendBase("updateGroup", args);
    }

    public boolean recv_updateGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      updateGroup_result result = new updateGroup_result();
      receiveBase(result, "updateGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateGroup failed: unknown result");
    }

    public boolean isGroupExists(java.lang.String domainId, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_isGroupExists(domainId, groupId);
      return recv_isGroupExists();
    }

    public void send_isGroupExists(java.lang.String domainId, java.lang.String groupId) throws org.apache.thrift.TException
    {
      isGroupExists_args args = new isGroupExists_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      sendBase("isGroupExists", args);
    }

    public boolean recv_isGroupExists() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      isGroupExists_result result = new isGroupExists_result();
      receiveBase(result, "isGroupExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isGroupExists failed: unknown result");
    }

    public boolean deleteGroup(java.lang.String domainId, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_deleteGroup(domainId, groupId);
      return recv_deleteGroup();
    }

    public void send_deleteGroup(java.lang.String domainId, java.lang.String groupId) throws org.apache.thrift.TException
    {
      deleteGroup_args args = new deleteGroup_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      sendBase("deleteGroup", args);
    }

    public boolean recv_deleteGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      deleteGroup_result result = new deleteGroup_result();
      receiveBase(result, "deleteGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteGroup failed: unknown result");
    }

    public org.apache.airavata.sharing.registry.models.UserGroup getGroup(java.lang.String domainId, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getGroup(domainId, groupId);
      return recv_getGroup();
    }

    public void send_getGroup(java.lang.String domainId, java.lang.String groupId) throws org.apache.thrift.TException
    {
      getGroup_args args = new getGroup_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      sendBase("getGroup", args);
    }

    public org.apache.airavata.sharing.registry.models.UserGroup recv_getGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getGroup_result result = new getGroup_result();
      receiveBase(result, "getGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGroup failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getGroups(java.lang.String domainId, int offset, int limit) throws org.apache.thrift.TException
    {
      send_getGroups(domainId, offset, limit);
      return recv_getGroups();
    }

    public void send_getGroups(java.lang.String domainId, int offset, int limit) throws org.apache.thrift.TException
    {
      getGroups_args args = new getGroups_args();
      args.setDomainId(domainId);
      args.setOffset(offset);
      args.setLimit(limit);
      sendBase("getGroups", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> recv_getGroups() throws org.apache.thrift.TException
    {
      getGroups_result result = new getGroups_result();
      receiveBase(result, "getGroups");
      if (result.isSetSuccess()) {
        return result.success;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGroups failed: unknown result");
    }

    public boolean addUsersToGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_addUsersToGroup(domainId, userIds, groupId);
      return recv_addUsersToGroup();
    }

    public void send_addUsersToGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId) throws org.apache.thrift.TException
    {
      addUsersToGroup_args args = new addUsersToGroup_args();
      args.setDomainId(domainId);
      args.setUserIds(userIds);
      args.setGroupId(groupId);
      sendBase("addUsersToGroup", args);
    }

    public boolean recv_addUsersToGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      addUsersToGroup_result result = new addUsersToGroup_result();
      receiveBase(result, "addUsersToGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addUsersToGroup failed: unknown result");
    }

    public boolean removeUsersFromGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_removeUsersFromGroup(domainId, userIds, groupId);
      return recv_removeUsersFromGroup();
    }

    public void send_removeUsersFromGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId) throws org.apache.thrift.TException
    {
      removeUsersFromGroup_args args = new removeUsersFromGroup_args();
      args.setDomainId(domainId);
      args.setUserIds(userIds);
      args.setGroupId(groupId);
      sendBase("removeUsersFromGroup", args);
    }

    public boolean recv_removeUsersFromGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      removeUsersFromGroup_result result = new removeUsersFromGroup_result();
      receiveBase(result, "removeUsersFromGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "removeUsersFromGroup failed: unknown result");
    }

    public boolean transferGroupOwnership(java.lang.String domainId, java.lang.String groupId, java.lang.String newOwnerId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_transferGroupOwnership(domainId, groupId, newOwnerId);
      return recv_transferGroupOwnership();
    }

    public void send_transferGroupOwnership(java.lang.String domainId, java.lang.String groupId, java.lang.String newOwnerId) throws org.apache.thrift.TException
    {
      transferGroupOwnership_args args = new transferGroupOwnership_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      args.setNewOwnerId(newOwnerId);
      sendBase("transferGroupOwnership", args);
    }

    public boolean recv_transferGroupOwnership() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      transferGroupOwnership_result result = new transferGroupOwnership_result();
      receiveBase(result, "transferGroupOwnership");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "transferGroupOwnership failed: unknown result");
    }

    public boolean addGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_addGroupAdmins(domainId, groupId, adminIds);
      return recv_addGroupAdmins();
    }

    public void send_addGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds) throws org.apache.thrift.TException
    {
      addGroupAdmins_args args = new addGroupAdmins_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      args.setAdminIds(adminIds);
      sendBase("addGroupAdmins", args);
    }

    public boolean recv_addGroupAdmins() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      addGroupAdmins_result result = new addGroupAdmins_result();
      receiveBase(result, "addGroupAdmins");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addGroupAdmins failed: unknown result");
    }

    public boolean removeGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_removeGroupAdmins(domainId, groupId, adminIds);
      return recv_removeGroupAdmins();
    }

    public void send_removeGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds) throws org.apache.thrift.TException
    {
      removeGroupAdmins_args args = new removeGroupAdmins_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      args.setAdminIds(adminIds);
      sendBase("removeGroupAdmins", args);
    }

    public boolean recv_removeGroupAdmins() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      removeGroupAdmins_result result = new removeGroupAdmins_result();
      receiveBase(result, "removeGroupAdmins");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "removeGroupAdmins failed: unknown result");
    }

    public boolean hasAdminAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String adminId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_hasAdminAccess(domainId, groupId, adminId);
      return recv_hasAdminAccess();
    }

    public void send_hasAdminAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String adminId) throws org.apache.thrift.TException
    {
      hasAdminAccess_args args = new hasAdminAccess_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      args.setAdminId(adminId);
      sendBase("hasAdminAccess", args);
    }

    public boolean recv_hasAdminAccess() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      hasAdminAccess_result result = new hasAdminAccess_result();
      receiveBase(result, "hasAdminAccess");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasAdminAccess failed: unknown result");
    }

    public boolean hasOwnerAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String ownerId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_hasOwnerAccess(domainId, groupId, ownerId);
      return recv_hasOwnerAccess();
    }

    public void send_hasOwnerAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String ownerId) throws org.apache.thrift.TException
    {
      hasOwnerAccess_args args = new hasOwnerAccess_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      args.setOwnerId(ownerId);
      sendBase("hasOwnerAccess", args);
    }

    public boolean recv_hasOwnerAccess() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      hasOwnerAccess_result result = new hasOwnerAccess_result();
      receiveBase(result, "hasOwnerAccess");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "hasOwnerAccess failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> getGroupMembersOfTypeUser(java.lang.String domainId, java.lang.String groupId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getGroupMembersOfTypeUser(domainId, groupId, offset, limit);
      return recv_getGroupMembersOfTypeUser();
    }

    public void send_getGroupMembersOfTypeUser(java.lang.String domainId, java.lang.String groupId, int offset, int limit) throws org.apache.thrift.TException
    {
      getGroupMembersOfTypeUser_args args = new getGroupMembersOfTypeUser_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      args.setOffset(offset);
      args.setLimit(limit);
      sendBase("getGroupMembersOfTypeUser", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> recv_getGroupMembersOfTypeUser() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getGroupMembersOfTypeUser_result result = new getGroupMembersOfTypeUser_result();
      receiveBase(result, "getGroupMembersOfTypeUser");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGroupMembersOfTypeUser failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getGroupMembersOfTypeGroup(java.lang.String domainId, java.lang.String groupId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getGroupMembersOfTypeGroup(domainId, groupId, offset, limit);
      return recv_getGroupMembersOfTypeGroup();
    }

    public void send_getGroupMembersOfTypeGroup(java.lang.String domainId, java.lang.String groupId, int offset, int limit) throws org.apache.thrift.TException
    {
      getGroupMembersOfTypeGroup_args args = new getGroupMembersOfTypeGroup_args();
      args.setDomainId(domainId);
      args.setGroupId(groupId);
      args.setOffset(offset);
      args.setLimit(limit);
      sendBase("getGroupMembersOfTypeGroup", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> recv_getGroupMembersOfTypeGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getGroupMembersOfTypeGroup_result result = new getGroupMembersOfTypeGroup_result();
      receiveBase(result, "getGroupMembersOfTypeGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getGroupMembersOfTypeGroup failed: unknown result");
    }

    public boolean addChildGroupsToParentGroup(java.lang.String domainId, java.util.List<java.lang.String> childIds, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_addChildGroupsToParentGroup(domainId, childIds, groupId);
      return recv_addChildGroupsToParentGroup();
    }

    public void send_addChildGroupsToParentGroup(java.lang.String domainId, java.util.List<java.lang.String> childIds, java.lang.String groupId) throws org.apache.thrift.TException
    {
      addChildGroupsToParentGroup_args args = new addChildGroupsToParentGroup_args();
      args.setDomainId(domainId);
      args.setChildIds(childIds);
      args.setGroupId(groupId);
      sendBase("addChildGroupsToParentGroup", args);
    }

    public boolean recv_addChildGroupsToParentGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      addChildGroupsToParentGroup_result result = new addChildGroupsToParentGroup_result();
      receiveBase(result, "addChildGroupsToParentGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "addChildGroupsToParentGroup failed: unknown result");
    }

    public boolean removeChildGroupFromParentGroup(java.lang.String domainId, java.lang.String childId, java.lang.String groupId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_removeChildGroupFromParentGroup(domainId, childId, groupId);
      return recv_removeChildGroupFromParentGroup();
    }

    public void send_removeChildGroupFromParentGroup(java.lang.String domainId, java.lang.String childId, java.lang.String groupId) throws org.apache.thrift.TException
    {
      removeChildGroupFromParentGroup_args args = new removeChildGroupFromParentGroup_args();
      args.setDomainId(domainId);
      args.setChildId(childId);
      args.setGroupId(groupId);
      sendBase("removeChildGroupFromParentGroup", args);
    }

    public boolean recv_removeChildGroupFromParentGroup() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      removeChildGroupFromParentGroup_result result = new removeChildGroupFromParentGroup_result();
      receiveBase(result, "removeChildGroupFromParentGroup");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "removeChildGroupFromParentGroup failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getAllMemberGroupsForUser(java.lang.String domainId, java.lang.String userId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getAllMemberGroupsForUser(domainId, userId);
      return recv_getAllMemberGroupsForUser();
    }

    public void send_getAllMemberGroupsForUser(java.lang.String domainId, java.lang.String userId) throws org.apache.thrift.TException
    {
      getAllMemberGroupsForUser_args args = new getAllMemberGroupsForUser_args();
      args.setDomainId(domainId);
      args.setUserId(userId);
      sendBase("getAllMemberGroupsForUser", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> recv_getAllMemberGroupsForUser() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getAllMemberGroupsForUser_result result = new getAllMemberGroupsForUser_result();
      receiveBase(result, "getAllMemberGroupsForUser");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getAllMemberGroupsForUser failed: unknown result");
    }

    public java.lang.String createEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException
    {
      send_createEntityType(entityType);
      return recv_createEntityType();
    }

    public void send_createEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType) throws org.apache.thrift.TException
    {
      createEntityType_args args = new createEntityType_args();
      args.setEntityType(entityType);
      sendBase("createEntityType", args);
    }

    public java.lang.String recv_createEntityType() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException
    {
      createEntityType_result result = new createEntityType_result();
      receiveBase(result, "createEntityType");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      if (result.dee != null) {
        throw result.dee;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createEntityType failed: unknown result");
    }

    public boolean updateEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_updateEntityType(entityType);
      return recv_updateEntityType();
    }

    public void send_updateEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType) throws org.apache.thrift.TException
    {
      updateEntityType_args args = new updateEntityType_args();
      args.setEntityType(entityType);
      sendBase("updateEntityType", args);
    }

    public boolean recv_updateEntityType() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      updateEntityType_result result = new updateEntityType_result();
      receiveBase(result, "updateEntityType");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateEntityType failed: unknown result");
    }

    public boolean isEntityTypeExists(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_isEntityTypeExists(domainId, entityTypeId);
      return recv_isEntityTypeExists();
    }

    public void send_isEntityTypeExists(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.thrift.TException
    {
      isEntityTypeExists_args args = new isEntityTypeExists_args();
      args.setDomainId(domainId);
      args.setEntityTypeId(entityTypeId);
      sendBase("isEntityTypeExists", args);
    }

    public boolean recv_isEntityTypeExists() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      isEntityTypeExists_result result = new isEntityTypeExists_result();
      receiveBase(result, "isEntityTypeExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isEntityTypeExists failed: unknown result");
    }

    public boolean deleteEntityType(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_deleteEntityType(domainId, entityTypeId);
      return recv_deleteEntityType();
    }

    public void send_deleteEntityType(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.thrift.TException
    {
      deleteEntityType_args args = new deleteEntityType_args();
      args.setDomainId(domainId);
      args.setEntityTypeId(entityTypeId);
      sendBase("deleteEntityType", args);
    }

    public boolean recv_deleteEntityType() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      deleteEntityType_result result = new deleteEntityType_result();
      receiveBase(result, "deleteEntityType");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteEntityType failed: unknown result");
    }

    public org.apache.airavata.sharing.registry.models.EntityType getEntityType(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getEntityType(domainId, entityTypeId);
      return recv_getEntityType();
    }

    public void send_getEntityType(java.lang.String domainId, java.lang.String entityTypeId) throws org.apache.thrift.TException
    {
      getEntityType_args args = new getEntityType_args();
      args.setDomainId(domainId);
      args.setEntityTypeId(entityTypeId);
      sendBase("getEntityType", args);
    }

    public org.apache.airavata.sharing.registry.models.EntityType recv_getEntityType() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getEntityType_result result = new getEntityType_result();
      receiveBase(result, "getEntityType");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getEntityType failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.EntityType> getEntityTypes(java.lang.String domainId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getEntityTypes(domainId, offset, limit);
      return recv_getEntityTypes();
    }

    public void send_getEntityTypes(java.lang.String domainId, int offset, int limit) throws org.apache.thrift.TException
    {
      getEntityTypes_args args = new getEntityTypes_args();
      args.setDomainId(domainId);
      args.setOffset(offset);
      args.setLimit(limit);
      sendBase("getEntityTypes", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.EntityType> recv_getEntityTypes() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getEntityTypes_result result = new getEntityTypes_result();
      receiveBase(result, "getEntityTypes");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getEntityTypes failed: unknown result");
    }

    public java.lang.String createEntity(org.apache.airavata.sharing.registry.models.Entity entity) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_createEntity(entity);
      return recv_createEntity();
    }

    public void send_createEntity(org.apache.airavata.sharing.registry.models.Entity entity) throws org.apache.thrift.TException
    {
      createEntity_args args = new createEntity_args();
      args.setEntity(entity);
      sendBase("createEntity", args);
    }

    public java.lang.String recv_createEntity() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      createEntity_result result = new createEntity_result();
      receiveBase(result, "createEntity");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createEntity failed: unknown result");
    }

    public boolean updateEntity(org.apache.airavata.sharing.registry.models.Entity entity) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_updateEntity(entity);
      return recv_updateEntity();
    }

    public void send_updateEntity(org.apache.airavata.sharing.registry.models.Entity entity) throws org.apache.thrift.TException
    {
      updateEntity_args args = new updateEntity_args();
      args.setEntity(entity);
      sendBase("updateEntity", args);
    }

    public boolean recv_updateEntity() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      updateEntity_result result = new updateEntity_result();
      receiveBase(result, "updateEntity");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updateEntity failed: unknown result");
    }

    public boolean isEntityExists(java.lang.String domainId, java.lang.String entityId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_isEntityExists(domainId, entityId);
      return recv_isEntityExists();
    }

    public void send_isEntityExists(java.lang.String domainId, java.lang.String entityId) throws org.apache.thrift.TException
    {
      isEntityExists_args args = new isEntityExists_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      sendBase("isEntityExists", args);
    }

    public boolean recv_isEntityExists() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      isEntityExists_result result = new isEntityExists_result();
      receiveBase(result, "isEntityExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isEntityExists failed: unknown result");
    }

    public boolean deleteEntity(java.lang.String domainId, java.lang.String entityId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_deleteEntity(domainId, entityId);
      return recv_deleteEntity();
    }

    public void send_deleteEntity(java.lang.String domainId, java.lang.String entityId) throws org.apache.thrift.TException
    {
      deleteEntity_args args = new deleteEntity_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      sendBase("deleteEntity", args);
    }

    public boolean recv_deleteEntity() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      deleteEntity_result result = new deleteEntity_result();
      receiveBase(result, "deleteEntity");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deleteEntity failed: unknown result");
    }

    public org.apache.airavata.sharing.registry.models.Entity getEntity(java.lang.String domainId, java.lang.String entityId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getEntity(domainId, entityId);
      return recv_getEntity();
    }

    public void send_getEntity(java.lang.String domainId, java.lang.String entityId) throws org.apache.thrift.TException
    {
      getEntity_args args = new getEntity_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      sendBase("getEntity", args);
    }

    public org.apache.airavata.sharing.registry.models.Entity recv_getEntity() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getEntity_result result = new getEntity_result();
      receiveBase(result, "getEntity");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getEntity failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.Entity> searchEntities(java.lang.String domainId, java.lang.String userId, java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_searchEntities(domainId, userId, filters, offset, limit);
      return recv_searchEntities();
    }

    public void send_searchEntities(java.lang.String domainId, java.lang.String userId, java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters, int offset, int limit) throws org.apache.thrift.TException
    {
      searchEntities_args args = new searchEntities_args();
      args.setDomainId(domainId);
      args.setUserId(userId);
      args.setFilters(filters);
      args.setOffset(offset);
      args.setLimit(limit);
      sendBase("searchEntities", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.Entity> recv_searchEntities() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      searchEntities_result result = new searchEntities_result();
      receiveBase(result, "searchEntities");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "searchEntities failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> getListOfSharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getListOfSharedUsers(domainId, entityId, permissionTypeId);
      return recv_getListOfSharedUsers();
    }

    public void send_getListOfSharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      getListOfSharedUsers_args args = new getListOfSharedUsers_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("getListOfSharedUsers", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> recv_getListOfSharedUsers() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getListOfSharedUsers_result result = new getListOfSharedUsers_result();
      receiveBase(result, "getListOfSharedUsers");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getListOfSharedUsers failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> getListOfDirectlySharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getListOfDirectlySharedUsers(domainId, entityId, permissionTypeId);
      return recv_getListOfDirectlySharedUsers();
    }

    public void send_getListOfDirectlySharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      getListOfDirectlySharedUsers_args args = new getListOfDirectlySharedUsers_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("getListOfDirectlySharedUsers", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> recv_getListOfDirectlySharedUsers() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getListOfDirectlySharedUsers_result result = new getListOfDirectlySharedUsers_result();
      receiveBase(result, "getListOfDirectlySharedUsers");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getListOfDirectlySharedUsers failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getListOfSharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getListOfSharedGroups(domainId, entityId, permissionTypeId);
      return recv_getListOfSharedGroups();
    }

    public void send_getListOfSharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      getListOfSharedGroups_args args = new getListOfSharedGroups_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("getListOfSharedGroups", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> recv_getListOfSharedGroups() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getListOfSharedGroups_result result = new getListOfSharedGroups_result();
      receiveBase(result, "getListOfSharedGroups");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getListOfSharedGroups failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getListOfDirectlySharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getListOfDirectlySharedGroups(domainId, entityId, permissionTypeId);
      return recv_getListOfDirectlySharedGroups();
    }

    public void send_getListOfDirectlySharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      getListOfDirectlySharedGroups_args args = new getListOfDirectlySharedGroups_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("getListOfDirectlySharedGroups", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> recv_getListOfDirectlySharedGroups() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getListOfDirectlySharedGroups_result result = new getListOfDirectlySharedGroups_result();
      receiveBase(result, "getListOfDirectlySharedGroups");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getListOfDirectlySharedGroups failed: unknown result");
    }

    public java.lang.String createPermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException
    {
      send_createPermissionType(permissionType);
      return recv_createPermissionType();
    }

    public void send_createPermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType) throws org.apache.thrift.TException
    {
      createPermissionType_args args = new createPermissionType_args();
      args.setPermissionType(permissionType);
      sendBase("createPermissionType", args);
    }

    public java.lang.String recv_createPermissionType() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException
    {
      createPermissionType_result result = new createPermissionType_result();
      receiveBase(result, "createPermissionType");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      if (result.dee != null) {
        throw result.dee;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "createPermissionType failed: unknown result");
    }

    public boolean updatePermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_updatePermissionType(permissionType);
      return recv_updatePermissionType();
    }

    public void send_updatePermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType) throws org.apache.thrift.TException
    {
      updatePermissionType_args args = new updatePermissionType_args();
      args.setPermissionType(permissionType);
      sendBase("updatePermissionType", args);
    }

    public boolean recv_updatePermissionType() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      updatePermissionType_result result = new updatePermissionType_result();
      receiveBase(result, "updatePermissionType");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "updatePermissionType failed: unknown result");
    }

    public boolean isPermissionExists(java.lang.String dimainId, java.lang.String permissionId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_isPermissionExists(dimainId, permissionId);
      return recv_isPermissionExists();
    }

    public void send_isPermissionExists(java.lang.String dimainId, java.lang.String permissionId) throws org.apache.thrift.TException
    {
      isPermissionExists_args args = new isPermissionExists_args();
      args.setDimainId(dimainId);
      args.setPermissionId(permissionId);
      sendBase("isPermissionExists", args);
    }

    public boolean recv_isPermissionExists() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      isPermissionExists_result result = new isPermissionExists_result();
      receiveBase(result, "isPermissionExists");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "isPermissionExists failed: unknown result");
    }

    public boolean deletePermissionType(java.lang.String domainId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_deletePermissionType(domainId, permissionTypeId);
      return recv_deletePermissionType();
    }

    public void send_deletePermissionType(java.lang.String domainId, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      deletePermissionType_args args = new deletePermissionType_args();
      args.setDomainId(domainId);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("deletePermissionType", args);
    }

    public boolean recv_deletePermissionType() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      deletePermissionType_result result = new deletePermissionType_result();
      receiveBase(result, "deletePermissionType");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "deletePermissionType failed: unknown result");
    }

    public org.apache.airavata.sharing.registry.models.PermissionType getPermissionType(java.lang.String domainId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getPermissionType(domainId, permissionTypeId);
      return recv_getPermissionType();
    }

    public void send_getPermissionType(java.lang.String domainId, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      getPermissionType_args args = new getPermissionType_args();
      args.setDomainId(domainId);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("getPermissionType", args);
    }

    public org.apache.airavata.sharing.registry.models.PermissionType recv_getPermissionType() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getPermissionType_result result = new getPermissionType_result();
      receiveBase(result, "getPermissionType");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getPermissionType failed: unknown result");
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> getPermissionTypes(java.lang.String domainId, int offset, int limit) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_getPermissionTypes(domainId, offset, limit);
      return recv_getPermissionTypes();
    }

    public void send_getPermissionTypes(java.lang.String domainId, int offset, int limit) throws org.apache.thrift.TException
    {
      getPermissionTypes_args args = new getPermissionTypes_args();
      args.setDomainId(domainId);
      args.setOffset(offset);
      args.setLimit(limit);
      sendBase("getPermissionTypes", args);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> recv_getPermissionTypes() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      getPermissionTypes_result result = new getPermissionTypes_result();
      receiveBase(result, "getPermissionTypes");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "getPermissionTypes failed: unknown result");
    }

    public boolean shareEntityWithUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, boolean cascadePermission) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_shareEntityWithUsers(domainId, entityId, userList, permissionTypeId, cascadePermission);
      return recv_shareEntityWithUsers();
    }

    public void send_shareEntityWithUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, boolean cascadePermission) throws org.apache.thrift.TException
    {
      shareEntityWithUsers_args args = new shareEntityWithUsers_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      args.setUserList(userList);
      args.setPermissionTypeId(permissionTypeId);
      args.setCascadePermission(cascadePermission);
      sendBase("shareEntityWithUsers", args);
    }

    public boolean recv_shareEntityWithUsers() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      shareEntityWithUsers_result result = new shareEntityWithUsers_result();
      receiveBase(result, "shareEntityWithUsers");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "shareEntityWithUsers failed: unknown result");
    }

    public boolean revokeEntitySharingFromUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_revokeEntitySharingFromUsers(domainId, entityId, userList, permissionTypeId);
      return recv_revokeEntitySharingFromUsers();
    }

    public void send_revokeEntitySharingFromUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      revokeEntitySharingFromUsers_args args = new revokeEntitySharingFromUsers_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      args.setUserList(userList);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("revokeEntitySharingFromUsers", args);
    }

    public boolean recv_revokeEntitySharingFromUsers() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      revokeEntitySharingFromUsers_result result = new revokeEntitySharingFromUsers_result();
      receiveBase(result, "revokeEntitySharingFromUsers");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "revokeEntitySharingFromUsers failed: unknown result");
    }

    public boolean shareEntityWithGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, boolean cascadePermission) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_shareEntityWithGroups(domainId, entityId, groupList, permissionTypeId, cascadePermission);
      return recv_shareEntityWithGroups();
    }

    public void send_shareEntityWithGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, boolean cascadePermission) throws org.apache.thrift.TException
    {
      shareEntityWithGroups_args args = new shareEntityWithGroups_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      args.setGroupList(groupList);
      args.setPermissionTypeId(permissionTypeId);
      args.setCascadePermission(cascadePermission);
      sendBase("shareEntityWithGroups", args);
    }

    public boolean recv_shareEntityWithGroups() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      shareEntityWithGroups_result result = new shareEntityWithGroups_result();
      receiveBase(result, "shareEntityWithGroups");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "shareEntityWithGroups failed: unknown result");
    }

    public boolean revokeEntitySharingFromGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_revokeEntitySharingFromGroups(domainId, entityId, groupList, permissionTypeId);
      return recv_revokeEntitySharingFromGroups();
    }

    public void send_revokeEntitySharingFromGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      revokeEntitySharingFromGroups_args args = new revokeEntitySharingFromGroups_args();
      args.setDomainId(domainId);
      args.setEntityId(entityId);
      args.setGroupList(groupList);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("revokeEntitySharingFromGroups", args);
    }

    public boolean recv_revokeEntitySharingFromGroups() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      revokeEntitySharingFromGroups_result result = new revokeEntitySharingFromGroups_result();
      receiveBase(result, "revokeEntitySharingFromGroups");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "revokeEntitySharingFromGroups failed: unknown result");
    }

    public boolean userHasAccess(java.lang.String domainId, java.lang.String userId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      send_userHasAccess(domainId, userId, entityId, permissionTypeId);
      return recv_userHasAccess();
    }

    public void send_userHasAccess(java.lang.String domainId, java.lang.String userId, java.lang.String entityId, java.lang.String permissionTypeId) throws org.apache.thrift.TException
    {
      userHasAccess_args args = new userHasAccess_args();
      args.setDomainId(domainId);
      args.setUserId(userId);
      args.setEntityId(entityId);
      args.setPermissionTypeId(permissionTypeId);
      sendBase("userHasAccess", args);
    }

    public boolean recv_userHasAccess() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException
    {
      userHasAccess_result result = new userHasAccess_result();
      receiveBase(result, "userHasAccess");
      if (result.isSetSuccess()) {
        return result.success;
      }
      if (result.sre != null) {
        throw result.sre;
      }
      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "userHasAccess failed: unknown result");
    }

  }
  public static class AsyncClient extends org.apache.airavata.base.api.BaseAPI.AsyncClient implements AsyncIface {
    public static class Factory implements org.apache.thrift.async.TAsyncClientFactory<AsyncClient> {
      private org.apache.thrift.async.TAsyncClientManager clientManager;
      private org.apache.thrift.protocol.TProtocolFactory protocolFactory;
      public Factory(org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.protocol.TProtocolFactory protocolFactory) {
        this.clientManager = clientManager;
        this.protocolFactory = protocolFactory;
      }
      public AsyncClient getAsyncClient(org.apache.thrift.transport.TNonblockingTransport transport) {
        return new AsyncClient(protocolFactory, clientManager, transport);
      }
    }

    public AsyncClient(org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.async.TAsyncClientManager clientManager, org.apache.thrift.transport.TNonblockingTransport transport) {
      super(protocolFactory, clientManager, transport);
    }

    public void createDomain(org.apache.airavata.sharing.registry.models.Domain domain, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createDomain_call method_call = new createDomain_call(domain, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class createDomain_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private org.apache.airavata.sharing.registry.models.Domain domain;
      public createDomain_call(org.apache.airavata.sharing.registry.models.Domain domain, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domain = domain;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createDomain", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createDomain_args args = new createDomain_args();
        args.setDomain(domain);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createDomain();
      }
    }

    public void updateDomain(org.apache.airavata.sharing.registry.models.Domain domain, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateDomain_call method_call = new updateDomain_call(domain, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateDomain_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.sharing.registry.models.Domain domain;
      public updateDomain_call(org.apache.airavata.sharing.registry.models.Domain domain, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domain = domain;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateDomain", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateDomain_args args = new updateDomain_args();
        args.setDomain(domain);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateDomain();
      }
    }

    public void isDomainExists(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isDomainExists_call method_call = new isDomainExists_call(domainId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isDomainExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      public isDomainExists_call(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isDomainExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isDomainExists_args args = new isDomainExists_args();
        args.setDomainId(domainId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isDomainExists();
      }
    }

    public void deleteDomain(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteDomain_call method_call = new deleteDomain_call(domainId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteDomain_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      public deleteDomain_call(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteDomain", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteDomain_args args = new deleteDomain_args();
        args.setDomainId(domainId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteDomain();
      }
    }

    public void getDomain(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Domain> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getDomain_call method_call = new getDomain_call(domainId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getDomain_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.sharing.registry.models.Domain> {
      private java.lang.String domainId;
      public getDomain_call(java.lang.String domainId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Domain> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getDomain", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getDomain_args args = new getDomain_args();
        args.setDomainId(domainId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.sharing.registry.models.Domain getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getDomain();
      }
    }

    public void getDomains(int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Domain>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getDomains_call method_call = new getDomains_call(offset, limit, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getDomains_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.Domain>> {
      private int offset;
      private int limit;
      public getDomains_call(int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Domain>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.offset = offset;
        this.limit = limit;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getDomains", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getDomains_args args = new getDomains_args();
        args.setOffset(offset);
        args.setLimit(limit);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.Domain> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getDomains();
      }
    }

    public void createUser(org.apache.airavata.sharing.registry.models.User user, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createUser_call method_call = new createUser_call(user, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class createUser_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private org.apache.airavata.sharing.registry.models.User user;
      public createUser_call(org.apache.airavata.sharing.registry.models.User user, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.user = user;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createUser_args args = new createUser_args();
        args.setUser(user);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createUser();
      }
    }

    public void updatedUser(org.apache.airavata.sharing.registry.models.User user, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updatedUser_call method_call = new updatedUser_call(user, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updatedUser_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.sharing.registry.models.User user;
      public updatedUser_call(org.apache.airavata.sharing.registry.models.User user, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.user = user;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updatedUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updatedUser_args args = new updatedUser_args();
        args.setUser(user);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updatedUser();
      }
    }

    public void isUserExists(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isUserExists_call method_call = new isUserExists_call(domainId, userId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isUserExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String userId;
      public isUserExists_call(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.userId = userId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isUserExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isUserExists_args args = new isUserExists_args();
        args.setDomainId(domainId);
        args.setUserId(userId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isUserExists();
      }
    }

    public void deleteUser(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteUser_call method_call = new deleteUser_call(domainId, userId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteUser_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String userId;
      public deleteUser_call(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.userId = userId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteUser_args args = new deleteUser_args();
        args.setDomainId(domainId);
        args.setUserId(userId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteUser();
      }
    }

    public void getUser(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.User> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getUser_call method_call = new getUser_call(domainId, userId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getUser_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.sharing.registry.models.User> {
      private java.lang.String domainId;
      private java.lang.String userId;
      public getUser_call(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.User> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.userId = userId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getUser_args args = new getUser_args();
        args.setDomainId(domainId);
        args.setUserId(userId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.sharing.registry.models.User getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getUser();
      }
    }

    public void getUsers(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getUsers_call method_call = new getUsers_call(domainId, offset, limit, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getUsers_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.User>> {
      private java.lang.String domainId;
      private int offset;
      private int limit;
      public getUsers_call(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.offset = offset;
        this.limit = limit;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getUsers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getUsers_args args = new getUsers_args();
        args.setDomainId(domainId);
        args.setOffset(offset);
        args.setLimit(limit);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.User> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getUsers();
      }
    }

    public void createGroup(org.apache.airavata.sharing.registry.models.UserGroup group, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createGroup_call method_call = new createGroup_call(group, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class createGroup_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private org.apache.airavata.sharing.registry.models.UserGroup group;
      public createGroup_call(org.apache.airavata.sharing.registry.models.UserGroup group, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.group = group;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createGroup_args args = new createGroup_args();
        args.setGroup(group);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createGroup();
      }
    }

    public void updateGroup(org.apache.airavata.sharing.registry.models.UserGroup group, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateGroup_call method_call = new updateGroup_call(group, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateGroup_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.sharing.registry.models.UserGroup group;
      public updateGroup_call(org.apache.airavata.sharing.registry.models.UserGroup group, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.group = group;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateGroup_args args = new updateGroup_args();
        args.setGroup(group);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateGroup();
      }
    }

    public void isGroupExists(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isGroupExists_call method_call = new isGroupExists_call(domainId, groupId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isGroupExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      public isGroupExists_call(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isGroupExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isGroupExists_args args = new isGroupExists_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isGroupExists();
      }
    }

    public void deleteGroup(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteGroup_call method_call = new deleteGroup_call(domainId, groupId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteGroup_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      public deleteGroup_call(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteGroup_args args = new deleteGroup_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteGroup();
      }
    }

    public void getGroup(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.UserGroup> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGroup_call method_call = new getGroup_call(domainId, groupId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getGroup_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.sharing.registry.models.UserGroup> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      public getGroup_call(java.lang.String domainId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.UserGroup> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGroup_args args = new getGroup_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.sharing.registry.models.UserGroup getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGroup();
      }
    }

    public void getGroups(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGroups_call method_call = new getGroups_call(domainId, offset, limit, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getGroups_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      private java.lang.String domainId;
      private int offset;
      private int limit;
      public getGroups_call(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.offset = offset;
        this.limit = limit;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getGroups", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGroups_args args = new getGroups_args();
        args.setDomainId(domainId);
        args.setOffset(offset);
        args.setLimit(limit);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getResult() throws org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGroups();
      }
    }

    public void addUsersToGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addUsersToGroup_call method_call = new addUsersToGroup_call(domainId, userIds, groupId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addUsersToGroup_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.util.List<java.lang.String> userIds;
      private java.lang.String groupId;
      public addUsersToGroup_call(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.userIds = userIds;
        this.groupId = groupId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addUsersToGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addUsersToGroup_args args = new addUsersToGroup_args();
        args.setDomainId(domainId);
        args.setUserIds(userIds);
        args.setGroupId(groupId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addUsersToGroup();
      }
    }

    public void removeUsersFromGroup(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      removeUsersFromGroup_call method_call = new removeUsersFromGroup_call(domainId, userIds, groupId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class removeUsersFromGroup_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.util.List<java.lang.String> userIds;
      private java.lang.String groupId;
      public removeUsersFromGroup_call(java.lang.String domainId, java.util.List<java.lang.String> userIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.userIds = userIds;
        this.groupId = groupId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeUsersFromGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeUsersFromGroup_args args = new removeUsersFromGroup_args();
        args.setDomainId(domainId);
        args.setUserIds(userIds);
        args.setGroupId(groupId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_removeUsersFromGroup();
      }
    }

    public void transferGroupOwnership(java.lang.String domainId, java.lang.String groupId, java.lang.String newOwnerId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      transferGroupOwnership_call method_call = new transferGroupOwnership_call(domainId, groupId, newOwnerId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class transferGroupOwnership_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      private java.lang.String newOwnerId;
      public transferGroupOwnership_call(java.lang.String domainId, java.lang.String groupId, java.lang.String newOwnerId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
        this.newOwnerId = newOwnerId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("transferGroupOwnership", org.apache.thrift.protocol.TMessageType.CALL, 0));
        transferGroupOwnership_args args = new transferGroupOwnership_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.setNewOwnerId(newOwnerId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_transferGroupOwnership();
      }
    }

    public void addGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addGroupAdmins_call method_call = new addGroupAdmins_call(domainId, groupId, adminIds, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addGroupAdmins_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      private java.util.List<java.lang.String> adminIds;
      public addGroupAdmins_call(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
        this.adminIds = adminIds;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addGroupAdmins", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addGroupAdmins_args args = new addGroupAdmins_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.setAdminIds(adminIds);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addGroupAdmins();
      }
    }

    public void removeGroupAdmins(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      removeGroupAdmins_call method_call = new removeGroupAdmins_call(domainId, groupId, adminIds, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class removeGroupAdmins_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      private java.util.List<java.lang.String> adminIds;
      public removeGroupAdmins_call(java.lang.String domainId, java.lang.String groupId, java.util.List<java.lang.String> adminIds, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
        this.adminIds = adminIds;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeGroupAdmins", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeGroupAdmins_args args = new removeGroupAdmins_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.setAdminIds(adminIds);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_removeGroupAdmins();
      }
    }

    public void hasAdminAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String adminId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      hasAdminAccess_call method_call = new hasAdminAccess_call(domainId, groupId, adminId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class hasAdminAccess_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      private java.lang.String adminId;
      public hasAdminAccess_call(java.lang.String domainId, java.lang.String groupId, java.lang.String adminId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
        this.adminId = adminId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("hasAdminAccess", org.apache.thrift.protocol.TMessageType.CALL, 0));
        hasAdminAccess_args args = new hasAdminAccess_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.setAdminId(adminId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_hasAdminAccess();
      }
    }

    public void hasOwnerAccess(java.lang.String domainId, java.lang.String groupId, java.lang.String ownerId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      hasOwnerAccess_call method_call = new hasOwnerAccess_call(domainId, groupId, ownerId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class hasOwnerAccess_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      private java.lang.String ownerId;
      public hasOwnerAccess_call(java.lang.String domainId, java.lang.String groupId, java.lang.String ownerId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
        this.ownerId = ownerId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("hasOwnerAccess", org.apache.thrift.protocol.TMessageType.CALL, 0));
        hasOwnerAccess_args args = new hasOwnerAccess_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.setOwnerId(ownerId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_hasOwnerAccess();
      }
    }

    public void getGroupMembersOfTypeUser(java.lang.String domainId, java.lang.String groupId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGroupMembersOfTypeUser_call method_call = new getGroupMembersOfTypeUser_call(domainId, groupId, offset, limit, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getGroupMembersOfTypeUser_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.User>> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      private int offset;
      private int limit;
      public getGroupMembersOfTypeUser_call(java.lang.String domainId, java.lang.String groupId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
        this.offset = offset;
        this.limit = limit;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getGroupMembersOfTypeUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGroupMembersOfTypeUser_args args = new getGroupMembersOfTypeUser_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.setOffset(offset);
        args.setLimit(limit);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.User> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGroupMembersOfTypeUser();
      }
    }

    public void getGroupMembersOfTypeGroup(java.lang.String domainId, java.lang.String groupId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getGroupMembersOfTypeGroup_call method_call = new getGroupMembersOfTypeGroup_call(domainId, groupId, offset, limit, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getGroupMembersOfTypeGroup_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      private java.lang.String domainId;
      private java.lang.String groupId;
      private int offset;
      private int limit;
      public getGroupMembersOfTypeGroup_call(java.lang.String domainId, java.lang.String groupId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.groupId = groupId;
        this.offset = offset;
        this.limit = limit;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getGroupMembersOfTypeGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getGroupMembersOfTypeGroup_args args = new getGroupMembersOfTypeGroup_args();
        args.setDomainId(domainId);
        args.setGroupId(groupId);
        args.setOffset(offset);
        args.setLimit(limit);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getGroupMembersOfTypeGroup();
      }
    }

    public void addChildGroupsToParentGroup(java.lang.String domainId, java.util.List<java.lang.String> childIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      addChildGroupsToParentGroup_call method_call = new addChildGroupsToParentGroup_call(domainId, childIds, groupId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class addChildGroupsToParentGroup_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.util.List<java.lang.String> childIds;
      private java.lang.String groupId;
      public addChildGroupsToParentGroup_call(java.lang.String domainId, java.util.List<java.lang.String> childIds, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.childIds = childIds;
        this.groupId = groupId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("addChildGroupsToParentGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        addChildGroupsToParentGroup_args args = new addChildGroupsToParentGroup_args();
        args.setDomainId(domainId);
        args.setChildIds(childIds);
        args.setGroupId(groupId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_addChildGroupsToParentGroup();
      }
    }

    public void removeChildGroupFromParentGroup(java.lang.String domainId, java.lang.String childId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      removeChildGroupFromParentGroup_call method_call = new removeChildGroupFromParentGroup_call(domainId, childId, groupId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class removeChildGroupFromParentGroup_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String childId;
      private java.lang.String groupId;
      public removeChildGroupFromParentGroup_call(java.lang.String domainId, java.lang.String childId, java.lang.String groupId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.childId = childId;
        this.groupId = groupId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("removeChildGroupFromParentGroup", org.apache.thrift.protocol.TMessageType.CALL, 0));
        removeChildGroupFromParentGroup_args args = new removeChildGroupFromParentGroup_args();
        args.setDomainId(domainId);
        args.setChildId(childId);
        args.setGroupId(groupId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_removeChildGroupFromParentGroup();
      }
    }

    public void getAllMemberGroupsForUser(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getAllMemberGroupsForUser_call method_call = new getAllMemberGroupsForUser_call(domainId, userId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getAllMemberGroupsForUser_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      private java.lang.String domainId;
      private java.lang.String userId;
      public getAllMemberGroupsForUser_call(java.lang.String domainId, java.lang.String userId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.userId = userId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getAllMemberGroupsForUser", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getAllMemberGroupsForUser_args args = new getAllMemberGroupsForUser_args();
        args.setDomainId(domainId);
        args.setUserId(userId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getAllMemberGroupsForUser();
      }
    }

    public void createEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createEntityType_call method_call = new createEntityType_call(entityType, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class createEntityType_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private org.apache.airavata.sharing.registry.models.EntityType entityType;
      public createEntityType_call(org.apache.airavata.sharing.registry.models.EntityType entityType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.entityType = entityType;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createEntityType", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createEntityType_args args = new createEntityType_args();
        args.setEntityType(entityType);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createEntityType();
      }
    }

    public void updateEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateEntityType_call method_call = new updateEntityType_call(entityType, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateEntityType_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.sharing.registry.models.EntityType entityType;
      public updateEntityType_call(org.apache.airavata.sharing.registry.models.EntityType entityType, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.entityType = entityType;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateEntityType", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateEntityType_args args = new updateEntityType_args();
        args.setEntityType(entityType);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateEntityType();
      }
    }

    public void isEntityTypeExists(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isEntityTypeExists_call method_call = new isEntityTypeExists_call(domainId, entityTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isEntityTypeExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String entityTypeId;
      public isEntityTypeExists_call(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityTypeId = entityTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isEntityTypeExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isEntityTypeExists_args args = new isEntityTypeExists_args();
        args.setDomainId(domainId);
        args.setEntityTypeId(entityTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isEntityTypeExists();
      }
    }

    public void deleteEntityType(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteEntityType_call method_call = new deleteEntityType_call(domainId, entityTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteEntityType_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String entityTypeId;
      public deleteEntityType_call(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityTypeId = entityTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteEntityType", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteEntityType_args args = new deleteEntityType_args();
        args.setDomainId(domainId);
        args.setEntityTypeId(entityTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteEntityType();
      }
    }

    public void getEntityType(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.EntityType> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getEntityType_call method_call = new getEntityType_call(domainId, entityTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getEntityType_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.sharing.registry.models.EntityType> {
      private java.lang.String domainId;
      private java.lang.String entityTypeId;
      public getEntityType_call(java.lang.String domainId, java.lang.String entityTypeId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.EntityType> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityTypeId = entityTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getEntityType", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getEntityType_args args = new getEntityType_args();
        args.setDomainId(domainId);
        args.setEntityTypeId(entityTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.sharing.registry.models.EntityType getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getEntityType();
      }
    }

    public void getEntityTypes(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.EntityType>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getEntityTypes_call method_call = new getEntityTypes_call(domainId, offset, limit, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getEntityTypes_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.EntityType>> {
      private java.lang.String domainId;
      private int offset;
      private int limit;
      public getEntityTypes_call(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.EntityType>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.offset = offset;
        this.limit = limit;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getEntityTypes", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getEntityTypes_args args = new getEntityTypes_args();
        args.setDomainId(domainId);
        args.setOffset(offset);
        args.setLimit(limit);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.EntityType> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getEntityTypes();
      }
    }

    public void createEntity(org.apache.airavata.sharing.registry.models.Entity entity, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createEntity_call method_call = new createEntity_call(entity, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class createEntity_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private org.apache.airavata.sharing.registry.models.Entity entity;
      public createEntity_call(org.apache.airavata.sharing.registry.models.Entity entity, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.entity = entity;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createEntity", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createEntity_args args = new createEntity_args();
        args.setEntity(entity);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createEntity();
      }
    }

    public void updateEntity(org.apache.airavata.sharing.registry.models.Entity entity, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updateEntity_call method_call = new updateEntity_call(entity, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updateEntity_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.sharing.registry.models.Entity entity;
      public updateEntity_call(org.apache.airavata.sharing.registry.models.Entity entity, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.entity = entity;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updateEntity", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updateEntity_args args = new updateEntity_args();
        args.setEntity(entity);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updateEntity();
      }
    }

    public void isEntityExists(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isEntityExists_call method_call = new isEntityExists_call(domainId, entityId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isEntityExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      public isEntityExists_call(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isEntityExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isEntityExists_args args = new isEntityExists_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isEntityExists();
      }
    }

    public void deleteEntity(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deleteEntity_call method_call = new deleteEntity_call(domainId, entityId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deleteEntity_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      public deleteEntity_call(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deleteEntity", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deleteEntity_args args = new deleteEntity_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deleteEntity();
      }
    }

    public void getEntity(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Entity> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getEntity_call method_call = new getEntity_call(domainId, entityId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getEntity_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.sharing.registry.models.Entity> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      public getEntity_call(java.lang.String domainId, java.lang.String entityId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Entity> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getEntity", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getEntity_args args = new getEntity_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.sharing.registry.models.Entity getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getEntity();
      }
    }

    public void searchEntities(java.lang.String domainId, java.lang.String userId, java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Entity>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      searchEntities_call method_call = new searchEntities_call(domainId, userId, filters, offset, limit, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class searchEntities_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.Entity>> {
      private java.lang.String domainId;
      private java.lang.String userId;
      private java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters;
      private int offset;
      private int limit;
      public searchEntities_call(java.lang.String domainId, java.lang.String userId, java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Entity>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.userId = userId;
        this.filters = filters;
        this.offset = offset;
        this.limit = limit;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("searchEntities", org.apache.thrift.protocol.TMessageType.CALL, 0));
        searchEntities_args args = new searchEntities_args();
        args.setDomainId(domainId);
        args.setUserId(userId);
        args.setFilters(filters);
        args.setOffset(offset);
        args.setLimit(limit);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.Entity> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_searchEntities();
      }
    }

    public void getListOfSharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getListOfSharedUsers_call method_call = new getListOfSharedUsers_call(domainId, entityId, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getListOfSharedUsers_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.User>> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      private java.lang.String permissionTypeId;
      public getListOfSharedUsers_call(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getListOfSharedUsers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getListOfSharedUsers_args args = new getListOfSharedUsers_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.User> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getListOfSharedUsers();
      }
    }

    public void getListOfDirectlySharedUsers(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getListOfDirectlySharedUsers_call method_call = new getListOfDirectlySharedUsers_call(domainId, entityId, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getListOfDirectlySharedUsers_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.User>> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      private java.lang.String permissionTypeId;
      public getListOfDirectlySharedUsers_call(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getListOfDirectlySharedUsers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getListOfDirectlySharedUsers_args args = new getListOfDirectlySharedUsers_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.User> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getListOfDirectlySharedUsers();
      }
    }

    public void getListOfSharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getListOfSharedGroups_call method_call = new getListOfSharedGroups_call(domainId, entityId, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getListOfSharedGroups_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      private java.lang.String permissionTypeId;
      public getListOfSharedGroups_call(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getListOfSharedGroups", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getListOfSharedGroups_args args = new getListOfSharedGroups_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getListOfSharedGroups();
      }
    }

    public void getListOfDirectlySharedGroups(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getListOfDirectlySharedGroups_call method_call = new getListOfDirectlySharedGroups_call(domainId, entityId, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getListOfDirectlySharedGroups_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      private java.lang.String permissionTypeId;
      public getListOfDirectlySharedGroups_call(java.lang.String domainId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getListOfDirectlySharedGroups", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getListOfDirectlySharedGroups_args args = new getListOfDirectlySharedGroups_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getListOfDirectlySharedGroups();
      }
    }

    public void createPermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      createPermissionType_call method_call = new createPermissionType_call(permissionType, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class createPermissionType_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.String> {
      private org.apache.airavata.sharing.registry.models.PermissionType permissionType;
      public createPermissionType_call(org.apache.airavata.sharing.registry.models.PermissionType permissionType, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.permissionType = permissionType;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("createPermissionType", org.apache.thrift.protocol.TMessageType.CALL, 0));
        createPermissionType_args args = new createPermissionType_args();
        args.setPermissionType(permissionType);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.String getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.airavata.sharing.registry.models.DuplicateEntryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_createPermissionType();
      }
    }

    public void updatePermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      updatePermissionType_call method_call = new updatePermissionType_call(permissionType, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class updatePermissionType_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private org.apache.airavata.sharing.registry.models.PermissionType permissionType;
      public updatePermissionType_call(org.apache.airavata.sharing.registry.models.PermissionType permissionType, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.permissionType = permissionType;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("updatePermissionType", org.apache.thrift.protocol.TMessageType.CALL, 0));
        updatePermissionType_args args = new updatePermissionType_args();
        args.setPermissionType(permissionType);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_updatePermissionType();
      }
    }

    public void isPermissionExists(java.lang.String dimainId, java.lang.String permissionId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      isPermissionExists_call method_call = new isPermissionExists_call(dimainId, permissionId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class isPermissionExists_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String dimainId;
      private java.lang.String permissionId;
      public isPermissionExists_call(java.lang.String dimainId, java.lang.String permissionId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.dimainId = dimainId;
        this.permissionId = permissionId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("isPermissionExists", org.apache.thrift.protocol.TMessageType.CALL, 0));
        isPermissionExists_args args = new isPermissionExists_args();
        args.setDimainId(dimainId);
        args.setPermissionId(permissionId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_isPermissionExists();
      }
    }

    public void deletePermissionType(java.lang.String domainId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      deletePermissionType_call method_call = new deletePermissionType_call(domainId, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class deletePermissionType_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String permissionTypeId;
      public deletePermissionType_call(java.lang.String domainId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("deletePermissionType", org.apache.thrift.protocol.TMessageType.CALL, 0));
        deletePermissionType_args args = new deletePermissionType_args();
        args.setDomainId(domainId);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_deletePermissionType();
      }
    }

    public void getPermissionType(java.lang.String domainId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.PermissionType> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getPermissionType_call method_call = new getPermissionType_call(domainId, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getPermissionType_call extends org.apache.thrift.async.TAsyncMethodCall<org.apache.airavata.sharing.registry.models.PermissionType> {
      private java.lang.String domainId;
      private java.lang.String permissionTypeId;
      public getPermissionType_call(java.lang.String domainId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.PermissionType> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getPermissionType", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getPermissionType_args args = new getPermissionType_args();
        args.setDomainId(domainId);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public org.apache.airavata.sharing.registry.models.PermissionType getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getPermissionType();
      }
    }

    public void getPermissionTypes(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      getPermissionTypes_call method_call = new getPermissionTypes_call(domainId, offset, limit, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class getPermissionTypes_call extends org.apache.thrift.async.TAsyncMethodCall<java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>> {
      private java.lang.String domainId;
      private int offset;
      private int limit;
      public getPermissionTypes_call(java.lang.String domainId, int offset, int limit, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.offset = offset;
        this.limit = limit;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("getPermissionTypes", org.apache.thrift.protocol.TMessageType.CALL, 0));
        getPermissionTypes_args args = new getPermissionTypes_args();
        args.setDomainId(domainId);
        args.setOffset(offset);
        args.setLimit(limit);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_getPermissionTypes();
      }
    }

    public void shareEntityWithUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, boolean cascadePermission, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      shareEntityWithUsers_call method_call = new shareEntityWithUsers_call(domainId, entityId, userList, permissionTypeId, cascadePermission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class shareEntityWithUsers_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      private java.util.List<java.lang.String> userList;
      private java.lang.String permissionTypeId;
      private boolean cascadePermission;
      public shareEntityWithUsers_call(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, boolean cascadePermission, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
        this.userList = userList;
        this.permissionTypeId = permissionTypeId;
        this.cascadePermission = cascadePermission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("shareEntityWithUsers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        shareEntityWithUsers_args args = new shareEntityWithUsers_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.setUserList(userList);
        args.setPermissionTypeId(permissionTypeId);
        args.setCascadePermission(cascadePermission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_shareEntityWithUsers();
      }
    }

    public void revokeEntitySharingFromUsers(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      revokeEntitySharingFromUsers_call method_call = new revokeEntitySharingFromUsers_call(domainId, entityId, userList, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class revokeEntitySharingFromUsers_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      private java.util.List<java.lang.String> userList;
      private java.lang.String permissionTypeId;
      public revokeEntitySharingFromUsers_call(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> userList, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
        this.userList = userList;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("revokeEntitySharingFromUsers", org.apache.thrift.protocol.TMessageType.CALL, 0));
        revokeEntitySharingFromUsers_args args = new revokeEntitySharingFromUsers_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.setUserList(userList);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_revokeEntitySharingFromUsers();
      }
    }

    public void shareEntityWithGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, boolean cascadePermission, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      shareEntityWithGroups_call method_call = new shareEntityWithGroups_call(domainId, entityId, groupList, permissionTypeId, cascadePermission, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class shareEntityWithGroups_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      private java.util.List<java.lang.String> groupList;
      private java.lang.String permissionTypeId;
      private boolean cascadePermission;
      public shareEntityWithGroups_call(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, boolean cascadePermission, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
        this.groupList = groupList;
        this.permissionTypeId = permissionTypeId;
        this.cascadePermission = cascadePermission;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("shareEntityWithGroups", org.apache.thrift.protocol.TMessageType.CALL, 0));
        shareEntityWithGroups_args args = new shareEntityWithGroups_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.setGroupList(groupList);
        args.setPermissionTypeId(permissionTypeId);
        args.setCascadePermission(cascadePermission);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_shareEntityWithGroups();
      }
    }

    public void revokeEntitySharingFromGroups(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      revokeEntitySharingFromGroups_call method_call = new revokeEntitySharingFromGroups_call(domainId, entityId, groupList, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class revokeEntitySharingFromGroups_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String entityId;
      private java.util.List<java.lang.String> groupList;
      private java.lang.String permissionTypeId;
      public revokeEntitySharingFromGroups_call(java.lang.String domainId, java.lang.String entityId, java.util.List<java.lang.String> groupList, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.entityId = entityId;
        this.groupList = groupList;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("revokeEntitySharingFromGroups", org.apache.thrift.protocol.TMessageType.CALL, 0));
        revokeEntitySharingFromGroups_args args = new revokeEntitySharingFromGroups_args();
        args.setDomainId(domainId);
        args.setEntityId(entityId);
        args.setGroupList(groupList);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_revokeEntitySharingFromGroups();
      }
    }

    public void userHasAccess(java.lang.String domainId, java.lang.String userId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
      checkReady();
      userHasAccess_call method_call = new userHasAccess_call(domainId, userId, entityId, permissionTypeId, resultHandler, this, ___protocolFactory, ___transport);
      this.___currentMethod = method_call;
      ___manager.call(method_call);
    }

    public static class userHasAccess_call extends org.apache.thrift.async.TAsyncMethodCall<java.lang.Boolean> {
      private java.lang.String domainId;
      private java.lang.String userId;
      private java.lang.String entityId;
      private java.lang.String permissionTypeId;
      public userHasAccess_call(java.lang.String domainId, java.lang.String userId, java.lang.String entityId, java.lang.String permissionTypeId, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
        super(client, protocolFactory, transport, resultHandler, false);
        this.domainId = domainId;
        this.userId = userId;
        this.entityId = entityId;
        this.permissionTypeId = permissionTypeId;
      }

      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("userHasAccess", org.apache.thrift.protocol.TMessageType.CALL, 0));
        userHasAccess_args args = new userHasAccess_args();
        args.setDomainId(domainId);
        args.setUserId(userId);
        args.setEntityId(entityId);
        args.setPermissionTypeId(permissionTypeId);
        args.write(prot);
        prot.writeMessageEnd();
      }

      public java.lang.Boolean getResult() throws org.apache.airavata.sharing.registry.models.SharingRegistryException, org.apache.thrift.TException {
        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
          throw new java.lang.IllegalStateException("Method call not finished!");
        }
        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
        return (new Client(prot)).recv_userHasAccess();
      }
    }

  }

  public static class Processor<I extends Iface> extends org.apache.airavata.base.api.BaseAPI.Processor<I> implements org.apache.thrift.TProcessor {
    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(Processor.class.getName());
    public Processor(I iface) {
      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>>()));
    }

    protected Processor(I iface, java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends Iface> java.util.Map<java.lang.String,  org.apache.thrift.ProcessFunction<I, ? extends org.apache.thrift.TBase>> getProcessMap(java.util.Map<java.lang.String, org.apache.thrift.ProcessFunction<I, ? extends  org.apache.thrift.TBase>> processMap) {
      processMap.put("createDomain", new createDomain());
      processMap.put("updateDomain", new updateDomain());
      processMap.put("isDomainExists", new isDomainExists());
      processMap.put("deleteDomain", new deleteDomain());
      processMap.put("getDomain", new getDomain());
      processMap.put("getDomains", new getDomains());
      processMap.put("createUser", new createUser());
      processMap.put("updatedUser", new updatedUser());
      processMap.put("isUserExists", new isUserExists());
      processMap.put("deleteUser", new deleteUser());
      processMap.put("getUser", new getUser());
      processMap.put("getUsers", new getUsers());
      processMap.put("createGroup", new createGroup());
      processMap.put("updateGroup", new updateGroup());
      processMap.put("isGroupExists", new isGroupExists());
      processMap.put("deleteGroup", new deleteGroup());
      processMap.put("getGroup", new getGroup());
      processMap.put("getGroups", new getGroups());
      processMap.put("addUsersToGroup", new addUsersToGroup());
      processMap.put("removeUsersFromGroup", new removeUsersFromGroup());
      processMap.put("transferGroupOwnership", new transferGroupOwnership());
      processMap.put("addGroupAdmins", new addGroupAdmins());
      processMap.put("removeGroupAdmins", new removeGroupAdmins());
      processMap.put("hasAdminAccess", new hasAdminAccess());
      processMap.put("hasOwnerAccess", new hasOwnerAccess());
      processMap.put("getGroupMembersOfTypeUser", new getGroupMembersOfTypeUser());
      processMap.put("getGroupMembersOfTypeGroup", new getGroupMembersOfTypeGroup());
      processMap.put("addChildGroupsToParentGroup", new addChildGroupsToParentGroup());
      processMap.put("removeChildGroupFromParentGroup", new removeChildGroupFromParentGroup());
      processMap.put("getAllMemberGroupsForUser", new getAllMemberGroupsForUser());
      processMap.put("createEntityType", new createEntityType());
      processMap.put("updateEntityType", new updateEntityType());
      processMap.put("isEntityTypeExists", new isEntityTypeExists());
      processMap.put("deleteEntityType", new deleteEntityType());
      processMap.put("getEntityType", new getEntityType());
      processMap.put("getEntityTypes", new getEntityTypes());
      processMap.put("createEntity", new createEntity());
      processMap.put("updateEntity", new updateEntity());
      processMap.put("isEntityExists", new isEntityExists());
      processMap.put("deleteEntity", new deleteEntity());
      processMap.put("getEntity", new getEntity());
      processMap.put("searchEntities", new searchEntities());
      processMap.put("getListOfSharedUsers", new getListOfSharedUsers());
      processMap.put("getListOfDirectlySharedUsers", new getListOfDirectlySharedUsers());
      processMap.put("getListOfSharedGroups", new getListOfSharedGroups());
      processMap.put("getListOfDirectlySharedGroups", new getListOfDirectlySharedGroups());
      processMap.put("createPermissionType", new createPermissionType());
      processMap.put("updatePermissionType", new updatePermissionType());
      processMap.put("isPermissionExists", new isPermissionExists());
      processMap.put("deletePermissionType", new deletePermissionType());
      processMap.put("getPermissionType", new getPermissionType());
      processMap.put("getPermissionTypes", new getPermissionTypes());
      processMap.put("shareEntityWithUsers", new shareEntityWithUsers());
      processMap.put("revokeEntitySharingFromUsers", new revokeEntitySharingFromUsers());
      processMap.put("shareEntityWithGroups", new shareEntityWithGroups());
      processMap.put("revokeEntitySharingFromGroups", new revokeEntitySharingFromGroups());
      processMap.put("userHasAccess", new userHasAccess());
      return processMap;
    }

    public static class createDomain<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createDomain_args> {
      public createDomain() {
        super("createDomain");
      }

      public createDomain_args getEmptyArgsInstance() {
        return new createDomain_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createDomain_result getResult(I iface, createDomain_args args) throws org.apache.thrift.TException {
        createDomain_result result = new createDomain_result();
        try {
          result.success = iface.createDomain(args.domain);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        } catch (org.apache.airavata.sharing.registry.models.DuplicateEntryException dee) {
          result.dee = dee;
        }
        return result;
      }
    }

    public static class updateDomain<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateDomain_args> {
      public updateDomain() {
        super("updateDomain");
      }

      public updateDomain_args getEmptyArgsInstance() {
        return new updateDomain_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateDomain_result getResult(I iface, updateDomain_args args) throws org.apache.thrift.TException {
        updateDomain_result result = new updateDomain_result();
        try {
          result.success = iface.updateDomain(args.domain);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class isDomainExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isDomainExists_args> {
      public isDomainExists() {
        super("isDomainExists");
      }

      public isDomainExists_args getEmptyArgsInstance() {
        return new isDomainExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isDomainExists_result getResult(I iface, isDomainExists_args args) throws org.apache.thrift.TException {
        isDomainExists_result result = new isDomainExists_result();
        try {
          result.success = iface.isDomainExists(args.domainId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class deleteDomain<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteDomain_args> {
      public deleteDomain() {
        super("deleteDomain");
      }

      public deleteDomain_args getEmptyArgsInstance() {
        return new deleteDomain_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteDomain_result getResult(I iface, deleteDomain_args args) throws org.apache.thrift.TException {
        deleteDomain_result result = new deleteDomain_result();
        try {
          result.success = iface.deleteDomain(args.domainId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getDomain<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getDomain_args> {
      public getDomain() {
        super("getDomain");
      }

      public getDomain_args getEmptyArgsInstance() {
        return new getDomain_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getDomain_result getResult(I iface, getDomain_args args) throws org.apache.thrift.TException {
        getDomain_result result = new getDomain_result();
        try {
          result.success = iface.getDomain(args.domainId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getDomains<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getDomains_args> {
      public getDomains() {
        super("getDomains");
      }

      public getDomains_args getEmptyArgsInstance() {
        return new getDomains_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getDomains_result getResult(I iface, getDomains_args args) throws org.apache.thrift.TException {
        getDomains_result result = new getDomains_result();
        try {
          result.success = iface.getDomains(args.offset, args.limit);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class createUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createUser_args> {
      public createUser() {
        super("createUser");
      }

      public createUser_args getEmptyArgsInstance() {
        return new createUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createUser_result getResult(I iface, createUser_args args) throws org.apache.thrift.TException {
        createUser_result result = new createUser_result();
        try {
          result.success = iface.createUser(args.user);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        } catch (org.apache.airavata.sharing.registry.models.DuplicateEntryException dee) {
          result.dee = dee;
        }
        return result;
      }
    }

    public static class updatedUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updatedUser_args> {
      public updatedUser() {
        super("updatedUser");
      }

      public updatedUser_args getEmptyArgsInstance() {
        return new updatedUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updatedUser_result getResult(I iface, updatedUser_args args) throws org.apache.thrift.TException {
        updatedUser_result result = new updatedUser_result();
        try {
          result.success = iface.updatedUser(args.user);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class isUserExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isUserExists_args> {
      public isUserExists() {
        super("isUserExists");
      }

      public isUserExists_args getEmptyArgsInstance() {
        return new isUserExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isUserExists_result getResult(I iface, isUserExists_args args) throws org.apache.thrift.TException {
        isUserExists_result result = new isUserExists_result();
        try {
          result.success = iface.isUserExists(args.domainId, args.userId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class deleteUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteUser_args> {
      public deleteUser() {
        super("deleteUser");
      }

      public deleteUser_args getEmptyArgsInstance() {
        return new deleteUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteUser_result getResult(I iface, deleteUser_args args) throws org.apache.thrift.TException {
        deleteUser_result result = new deleteUser_result();
        try {
          result.success = iface.deleteUser(args.domainId, args.userId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getUser_args> {
      public getUser() {
        super("getUser");
      }

      public getUser_args getEmptyArgsInstance() {
        return new getUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getUser_result getResult(I iface, getUser_args args) throws org.apache.thrift.TException {
        getUser_result result = new getUser_result();
        try {
          result.success = iface.getUser(args.domainId, args.userId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getUsers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getUsers_args> {
      public getUsers() {
        super("getUsers");
      }

      public getUsers_args getEmptyArgsInstance() {
        return new getUsers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getUsers_result getResult(I iface, getUsers_args args) throws org.apache.thrift.TException {
        getUsers_result result = new getUsers_result();
        try {
          result.success = iface.getUsers(args.domainId, args.offset, args.limit);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class createGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createGroup_args> {
      public createGroup() {
        super("createGroup");
      }

      public createGroup_args getEmptyArgsInstance() {
        return new createGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createGroup_result getResult(I iface, createGroup_args args) throws org.apache.thrift.TException {
        createGroup_result result = new createGroup_result();
        try {
          result.success = iface.createGroup(args.group);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class updateGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateGroup_args> {
      public updateGroup() {
        super("updateGroup");
      }

      public updateGroup_args getEmptyArgsInstance() {
        return new updateGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateGroup_result getResult(I iface, updateGroup_args args) throws org.apache.thrift.TException {
        updateGroup_result result = new updateGroup_result();
        try {
          result.success = iface.updateGroup(args.group);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class isGroupExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isGroupExists_args> {
      public isGroupExists() {
        super("isGroupExists");
      }

      public isGroupExists_args getEmptyArgsInstance() {
        return new isGroupExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isGroupExists_result getResult(I iface, isGroupExists_args args) throws org.apache.thrift.TException {
        isGroupExists_result result = new isGroupExists_result();
        try {
          result.success = iface.isGroupExists(args.domainId, args.groupId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class deleteGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteGroup_args> {
      public deleteGroup() {
        super("deleteGroup");
      }

      public deleteGroup_args getEmptyArgsInstance() {
        return new deleteGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteGroup_result getResult(I iface, deleteGroup_args args) throws org.apache.thrift.TException {
        deleteGroup_result result = new deleteGroup_result();
        try {
          result.success = iface.deleteGroup(args.domainId, args.groupId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getGroup_args> {
      public getGroup() {
        super("getGroup");
      }

      public getGroup_args getEmptyArgsInstance() {
        return new getGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getGroup_result getResult(I iface, getGroup_args args) throws org.apache.thrift.TException {
        getGroup_result result = new getGroup_result();
        try {
          result.success = iface.getGroup(args.domainId, args.groupId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getGroups<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getGroups_args> {
      public getGroups() {
        super("getGroups");
      }

      public getGroups_args getEmptyArgsInstance() {
        return new getGroups_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getGroups_result getResult(I iface, getGroups_args args) throws org.apache.thrift.TException {
        getGroups_result result = new getGroups_result();
        result.success = iface.getGroups(args.domainId, args.offset, args.limit);
        return result;
      }
    }

    public static class addUsersToGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, addUsersToGroup_args> {
      public addUsersToGroup() {
        super("addUsersToGroup");
      }

      public addUsersToGroup_args getEmptyArgsInstance() {
        return new addUsersToGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public addUsersToGroup_result getResult(I iface, addUsersToGroup_args args) throws org.apache.thrift.TException {
        addUsersToGroup_result result = new addUsersToGroup_result();
        try {
          result.success = iface.addUsersToGroup(args.domainId, args.userIds, args.groupId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class removeUsersFromGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeUsersFromGroup_args> {
      public removeUsersFromGroup() {
        super("removeUsersFromGroup");
      }

      public removeUsersFromGroup_args getEmptyArgsInstance() {
        return new removeUsersFromGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeUsersFromGroup_result getResult(I iface, removeUsersFromGroup_args args) throws org.apache.thrift.TException {
        removeUsersFromGroup_result result = new removeUsersFromGroup_result();
        try {
          result.success = iface.removeUsersFromGroup(args.domainId, args.userIds, args.groupId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class transferGroupOwnership<I extends Iface> extends org.apache.thrift.ProcessFunction<I, transferGroupOwnership_args> {
      public transferGroupOwnership() {
        super("transferGroupOwnership");
      }

      public transferGroupOwnership_args getEmptyArgsInstance() {
        return new transferGroupOwnership_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public transferGroupOwnership_result getResult(I iface, transferGroupOwnership_args args) throws org.apache.thrift.TException {
        transferGroupOwnership_result result = new transferGroupOwnership_result();
        try {
          result.success = iface.transferGroupOwnership(args.domainId, args.groupId, args.newOwnerId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class addGroupAdmins<I extends Iface> extends org.apache.thrift.ProcessFunction<I, addGroupAdmins_args> {
      public addGroupAdmins() {
        super("addGroupAdmins");
      }

      public addGroupAdmins_args getEmptyArgsInstance() {
        return new addGroupAdmins_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public addGroupAdmins_result getResult(I iface, addGroupAdmins_args args) throws org.apache.thrift.TException {
        addGroupAdmins_result result = new addGroupAdmins_result();
        try {
          result.success = iface.addGroupAdmins(args.domainId, args.groupId, args.adminIds);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class removeGroupAdmins<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeGroupAdmins_args> {
      public removeGroupAdmins() {
        super("removeGroupAdmins");
      }

      public removeGroupAdmins_args getEmptyArgsInstance() {
        return new removeGroupAdmins_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeGroupAdmins_result getResult(I iface, removeGroupAdmins_args args) throws org.apache.thrift.TException {
        removeGroupAdmins_result result = new removeGroupAdmins_result();
        try {
          result.success = iface.removeGroupAdmins(args.domainId, args.groupId, args.adminIds);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class hasAdminAccess<I extends Iface> extends org.apache.thrift.ProcessFunction<I, hasAdminAccess_args> {
      public hasAdminAccess() {
        super("hasAdminAccess");
      }

      public hasAdminAccess_args getEmptyArgsInstance() {
        return new hasAdminAccess_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public hasAdminAccess_result getResult(I iface, hasAdminAccess_args args) throws org.apache.thrift.TException {
        hasAdminAccess_result result = new hasAdminAccess_result();
        try {
          result.success = iface.hasAdminAccess(args.domainId, args.groupId, args.adminId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class hasOwnerAccess<I extends Iface> extends org.apache.thrift.ProcessFunction<I, hasOwnerAccess_args> {
      public hasOwnerAccess() {
        super("hasOwnerAccess");
      }

      public hasOwnerAccess_args getEmptyArgsInstance() {
        return new hasOwnerAccess_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public hasOwnerAccess_result getResult(I iface, hasOwnerAccess_args args) throws org.apache.thrift.TException {
        hasOwnerAccess_result result = new hasOwnerAccess_result();
        try {
          result.success = iface.hasOwnerAccess(args.domainId, args.groupId, args.ownerId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getGroupMembersOfTypeUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getGroupMembersOfTypeUser_args> {
      public getGroupMembersOfTypeUser() {
        super("getGroupMembersOfTypeUser");
      }

      public getGroupMembersOfTypeUser_args getEmptyArgsInstance() {
        return new getGroupMembersOfTypeUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getGroupMembersOfTypeUser_result getResult(I iface, getGroupMembersOfTypeUser_args args) throws org.apache.thrift.TException {
        getGroupMembersOfTypeUser_result result = new getGroupMembersOfTypeUser_result();
        try {
          result.success = iface.getGroupMembersOfTypeUser(args.domainId, args.groupId, args.offset, args.limit);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getGroupMembersOfTypeGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getGroupMembersOfTypeGroup_args> {
      public getGroupMembersOfTypeGroup() {
        super("getGroupMembersOfTypeGroup");
      }

      public getGroupMembersOfTypeGroup_args getEmptyArgsInstance() {
        return new getGroupMembersOfTypeGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getGroupMembersOfTypeGroup_result getResult(I iface, getGroupMembersOfTypeGroup_args args) throws org.apache.thrift.TException {
        getGroupMembersOfTypeGroup_result result = new getGroupMembersOfTypeGroup_result();
        try {
          result.success = iface.getGroupMembersOfTypeGroup(args.domainId, args.groupId, args.offset, args.limit);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class addChildGroupsToParentGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, addChildGroupsToParentGroup_args> {
      public addChildGroupsToParentGroup() {
        super("addChildGroupsToParentGroup");
      }

      public addChildGroupsToParentGroup_args getEmptyArgsInstance() {
        return new addChildGroupsToParentGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public addChildGroupsToParentGroup_result getResult(I iface, addChildGroupsToParentGroup_args args) throws org.apache.thrift.TException {
        addChildGroupsToParentGroup_result result = new addChildGroupsToParentGroup_result();
        try {
          result.success = iface.addChildGroupsToParentGroup(args.domainId, args.childIds, args.groupId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class removeChildGroupFromParentGroup<I extends Iface> extends org.apache.thrift.ProcessFunction<I, removeChildGroupFromParentGroup_args> {
      public removeChildGroupFromParentGroup() {
        super("removeChildGroupFromParentGroup");
      }

      public removeChildGroupFromParentGroup_args getEmptyArgsInstance() {
        return new removeChildGroupFromParentGroup_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public removeChildGroupFromParentGroup_result getResult(I iface, removeChildGroupFromParentGroup_args args) throws org.apache.thrift.TException {
        removeChildGroupFromParentGroup_result result = new removeChildGroupFromParentGroup_result();
        try {
          result.success = iface.removeChildGroupFromParentGroup(args.domainId, args.childId, args.groupId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getAllMemberGroupsForUser<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getAllMemberGroupsForUser_args> {
      public getAllMemberGroupsForUser() {
        super("getAllMemberGroupsForUser");
      }

      public getAllMemberGroupsForUser_args getEmptyArgsInstance() {
        return new getAllMemberGroupsForUser_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getAllMemberGroupsForUser_result getResult(I iface, getAllMemberGroupsForUser_args args) throws org.apache.thrift.TException {
        getAllMemberGroupsForUser_result result = new getAllMemberGroupsForUser_result();
        try {
          result.success = iface.getAllMemberGroupsForUser(args.domainId, args.userId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class createEntityType<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createEntityType_args> {
      public createEntityType() {
        super("createEntityType");
      }

      public createEntityType_args getEmptyArgsInstance() {
        return new createEntityType_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createEntityType_result getResult(I iface, createEntityType_args args) throws org.apache.thrift.TException {
        createEntityType_result result = new createEntityType_result();
        try {
          result.success = iface.createEntityType(args.entityType);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        } catch (org.apache.airavata.sharing.registry.models.DuplicateEntryException dee) {
          result.dee = dee;
        }
        return result;
      }
    }

    public static class updateEntityType<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateEntityType_args> {
      public updateEntityType() {
        super("updateEntityType");
      }

      public updateEntityType_args getEmptyArgsInstance() {
        return new updateEntityType_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateEntityType_result getResult(I iface, updateEntityType_args args) throws org.apache.thrift.TException {
        updateEntityType_result result = new updateEntityType_result();
        try {
          result.success = iface.updateEntityType(args.entityType);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class isEntityTypeExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isEntityTypeExists_args> {
      public isEntityTypeExists() {
        super("isEntityTypeExists");
      }

      public isEntityTypeExists_args getEmptyArgsInstance() {
        return new isEntityTypeExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isEntityTypeExists_result getResult(I iface, isEntityTypeExists_args args) throws org.apache.thrift.TException {
        isEntityTypeExists_result result = new isEntityTypeExists_result();
        try {
          result.success = iface.isEntityTypeExists(args.domainId, args.entityTypeId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class deleteEntityType<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteEntityType_args> {
      public deleteEntityType() {
        super("deleteEntityType");
      }

      public deleteEntityType_args getEmptyArgsInstance() {
        return new deleteEntityType_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteEntityType_result getResult(I iface, deleteEntityType_args args) throws org.apache.thrift.TException {
        deleteEntityType_result result = new deleteEntityType_result();
        try {
          result.success = iface.deleteEntityType(args.domainId, args.entityTypeId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getEntityType<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getEntityType_args> {
      public getEntityType() {
        super("getEntityType");
      }

      public getEntityType_args getEmptyArgsInstance() {
        return new getEntityType_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getEntityType_result getResult(I iface, getEntityType_args args) throws org.apache.thrift.TException {
        getEntityType_result result = new getEntityType_result();
        try {
          result.success = iface.getEntityType(args.domainId, args.entityTypeId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getEntityTypes<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getEntityTypes_args> {
      public getEntityTypes() {
        super("getEntityTypes");
      }

      public getEntityTypes_args getEmptyArgsInstance() {
        return new getEntityTypes_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getEntityTypes_result getResult(I iface, getEntityTypes_args args) throws org.apache.thrift.TException {
        getEntityTypes_result result = new getEntityTypes_result();
        try {
          result.success = iface.getEntityTypes(args.domainId, args.offset, args.limit);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class createEntity<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createEntity_args> {
      public createEntity() {
        super("createEntity");
      }

      public createEntity_args getEmptyArgsInstance() {
        return new createEntity_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createEntity_result getResult(I iface, createEntity_args args) throws org.apache.thrift.TException {
        createEntity_result result = new createEntity_result();
        try {
          result.success = iface.createEntity(args.entity);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class updateEntity<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updateEntity_args> {
      public updateEntity() {
        super("updateEntity");
      }

      public updateEntity_args getEmptyArgsInstance() {
        return new updateEntity_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updateEntity_result getResult(I iface, updateEntity_args args) throws org.apache.thrift.TException {
        updateEntity_result result = new updateEntity_result();
        try {
          result.success = iface.updateEntity(args.entity);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class isEntityExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isEntityExists_args> {
      public isEntityExists() {
        super("isEntityExists");
      }

      public isEntityExists_args getEmptyArgsInstance() {
        return new isEntityExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isEntityExists_result getResult(I iface, isEntityExists_args args) throws org.apache.thrift.TException {
        isEntityExists_result result = new isEntityExists_result();
        try {
          result.success = iface.isEntityExists(args.domainId, args.entityId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class deleteEntity<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deleteEntity_args> {
      public deleteEntity() {
        super("deleteEntity");
      }

      public deleteEntity_args getEmptyArgsInstance() {
        return new deleteEntity_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deleteEntity_result getResult(I iface, deleteEntity_args args) throws org.apache.thrift.TException {
        deleteEntity_result result = new deleteEntity_result();
        try {
          result.success = iface.deleteEntity(args.domainId, args.entityId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getEntity<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getEntity_args> {
      public getEntity() {
        super("getEntity");
      }

      public getEntity_args getEmptyArgsInstance() {
        return new getEntity_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getEntity_result getResult(I iface, getEntity_args args) throws org.apache.thrift.TException {
        getEntity_result result = new getEntity_result();
        try {
          result.success = iface.getEntity(args.domainId, args.entityId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class searchEntities<I extends Iface> extends org.apache.thrift.ProcessFunction<I, searchEntities_args> {
      public searchEntities() {
        super("searchEntities");
      }

      public searchEntities_args getEmptyArgsInstance() {
        return new searchEntities_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public searchEntities_result getResult(I iface, searchEntities_args args) throws org.apache.thrift.TException {
        searchEntities_result result = new searchEntities_result();
        try {
          result.success = iface.searchEntities(args.domainId, args.userId, args.filters, args.offset, args.limit);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getListOfSharedUsers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getListOfSharedUsers_args> {
      public getListOfSharedUsers() {
        super("getListOfSharedUsers");
      }

      public getListOfSharedUsers_args getEmptyArgsInstance() {
        return new getListOfSharedUsers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getListOfSharedUsers_result getResult(I iface, getListOfSharedUsers_args args) throws org.apache.thrift.TException {
        getListOfSharedUsers_result result = new getListOfSharedUsers_result();
        try {
          result.success = iface.getListOfSharedUsers(args.domainId, args.entityId, args.permissionTypeId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getListOfDirectlySharedUsers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getListOfDirectlySharedUsers_args> {
      public getListOfDirectlySharedUsers() {
        super("getListOfDirectlySharedUsers");
      }

      public getListOfDirectlySharedUsers_args getEmptyArgsInstance() {
        return new getListOfDirectlySharedUsers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getListOfDirectlySharedUsers_result getResult(I iface, getListOfDirectlySharedUsers_args args) throws org.apache.thrift.TException {
        getListOfDirectlySharedUsers_result result = new getListOfDirectlySharedUsers_result();
        try {
          result.success = iface.getListOfDirectlySharedUsers(args.domainId, args.entityId, args.permissionTypeId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getListOfSharedGroups<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getListOfSharedGroups_args> {
      public getListOfSharedGroups() {
        super("getListOfSharedGroups");
      }

      public getListOfSharedGroups_args getEmptyArgsInstance() {
        return new getListOfSharedGroups_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getListOfSharedGroups_result getResult(I iface, getListOfSharedGroups_args args) throws org.apache.thrift.TException {
        getListOfSharedGroups_result result = new getListOfSharedGroups_result();
        try {
          result.success = iface.getListOfSharedGroups(args.domainId, args.entityId, args.permissionTypeId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getListOfDirectlySharedGroups<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getListOfDirectlySharedGroups_args> {
      public getListOfDirectlySharedGroups() {
        super("getListOfDirectlySharedGroups");
      }

      public getListOfDirectlySharedGroups_args getEmptyArgsInstance() {
        return new getListOfDirectlySharedGroups_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getListOfDirectlySharedGroups_result getResult(I iface, getListOfDirectlySharedGroups_args args) throws org.apache.thrift.TException {
        getListOfDirectlySharedGroups_result result = new getListOfDirectlySharedGroups_result();
        try {
          result.success = iface.getListOfDirectlySharedGroups(args.domainId, args.entityId, args.permissionTypeId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class createPermissionType<I extends Iface> extends org.apache.thrift.ProcessFunction<I, createPermissionType_args> {
      public createPermissionType() {
        super("createPermissionType");
      }

      public createPermissionType_args getEmptyArgsInstance() {
        return new createPermissionType_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public createPermissionType_result getResult(I iface, createPermissionType_args args) throws org.apache.thrift.TException {
        createPermissionType_result result = new createPermissionType_result();
        try {
          result.success = iface.createPermissionType(args.permissionType);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        } catch (org.apache.airavata.sharing.registry.models.DuplicateEntryException dee) {
          result.dee = dee;
        }
        return result;
      }
    }

    public static class updatePermissionType<I extends Iface> extends org.apache.thrift.ProcessFunction<I, updatePermissionType_args> {
      public updatePermissionType() {
        super("updatePermissionType");
      }

      public updatePermissionType_args getEmptyArgsInstance() {
        return new updatePermissionType_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public updatePermissionType_result getResult(I iface, updatePermissionType_args args) throws org.apache.thrift.TException {
        updatePermissionType_result result = new updatePermissionType_result();
        try {
          result.success = iface.updatePermissionType(args.permissionType);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class isPermissionExists<I extends Iface> extends org.apache.thrift.ProcessFunction<I, isPermissionExists_args> {
      public isPermissionExists() {
        super("isPermissionExists");
      }

      public isPermissionExists_args getEmptyArgsInstance() {
        return new isPermissionExists_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public isPermissionExists_result getResult(I iface, isPermissionExists_args args) throws org.apache.thrift.TException {
        isPermissionExists_result result = new isPermissionExists_result();
        try {
          result.success = iface.isPermissionExists(args.dimainId, args.permissionId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class deletePermissionType<I extends Iface> extends org.apache.thrift.ProcessFunction<I, deletePermissionType_args> {
      public deletePermissionType() {
        super("deletePermissionType");
      }

      public deletePermissionType_args getEmptyArgsInstance() {
        return new deletePermissionType_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public deletePermissionType_result getResult(I iface, deletePermissionType_args args) throws org.apache.thrift.TException {
        deletePermissionType_result result = new deletePermissionType_result();
        try {
          result.success = iface.deletePermissionType(args.domainId, args.permissionTypeId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getPermissionType<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getPermissionType_args> {
      public getPermissionType() {
        super("getPermissionType");
      }

      public getPermissionType_args getEmptyArgsInstance() {
        return new getPermissionType_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getPermissionType_result getResult(I iface, getPermissionType_args args) throws org.apache.thrift.TException {
        getPermissionType_result result = new getPermissionType_result();
        try {
          result.success = iface.getPermissionType(args.domainId, args.permissionTypeId);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class getPermissionTypes<I extends Iface> extends org.apache.thrift.ProcessFunction<I, getPermissionTypes_args> {
      public getPermissionTypes() {
        super("getPermissionTypes");
      }

      public getPermissionTypes_args getEmptyArgsInstance() {
        return new getPermissionTypes_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public getPermissionTypes_result getResult(I iface, getPermissionTypes_args args) throws org.apache.thrift.TException {
        getPermissionTypes_result result = new getPermissionTypes_result();
        try {
          result.success = iface.getPermissionTypes(args.domainId, args.offset, args.limit);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class shareEntityWithUsers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, shareEntityWithUsers_args> {
      public shareEntityWithUsers() {
        super("shareEntityWithUsers");
      }

      public shareEntityWithUsers_args getEmptyArgsInstance() {
        return new shareEntityWithUsers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public shareEntityWithUsers_result getResult(I iface, shareEntityWithUsers_args args) throws org.apache.thrift.TException {
        shareEntityWithUsers_result result = new shareEntityWithUsers_result();
        try {
          result.success = iface.shareEntityWithUsers(args.domainId, args.entityId, args.userList, args.permissionTypeId, args.cascadePermission);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class revokeEntitySharingFromUsers<I extends Iface> extends org.apache.thrift.ProcessFunction<I, revokeEntitySharingFromUsers_args> {
      public revokeEntitySharingFromUsers() {
        super("revokeEntitySharingFromUsers");
      }

      public revokeEntitySharingFromUsers_args getEmptyArgsInstance() {
        return new revokeEntitySharingFromUsers_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public revokeEntitySharingFromUsers_result getResult(I iface, revokeEntitySharingFromUsers_args args) throws org.apache.thrift.TException {
        revokeEntitySharingFromUsers_result result = new revokeEntitySharingFromUsers_result();
        try {
          result.success = iface.revokeEntitySharingFromUsers(args.domainId, args.entityId, args.userList, args.permissionTypeId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class shareEntityWithGroups<I extends Iface> extends org.apache.thrift.ProcessFunction<I, shareEntityWithGroups_args> {
      public shareEntityWithGroups() {
        super("shareEntityWithGroups");
      }

      public shareEntityWithGroups_args getEmptyArgsInstance() {
        return new shareEntityWithGroups_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public shareEntityWithGroups_result getResult(I iface, shareEntityWithGroups_args args) throws org.apache.thrift.TException {
        shareEntityWithGroups_result result = new shareEntityWithGroups_result();
        try {
          result.success = iface.shareEntityWithGroups(args.domainId, args.entityId, args.groupList, args.permissionTypeId, args.cascadePermission);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class revokeEntitySharingFromGroups<I extends Iface> extends org.apache.thrift.ProcessFunction<I, revokeEntitySharingFromGroups_args> {
      public revokeEntitySharingFromGroups() {
        super("revokeEntitySharingFromGroups");
      }

      public revokeEntitySharingFromGroups_args getEmptyArgsInstance() {
        return new revokeEntitySharingFromGroups_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public revokeEntitySharingFromGroups_result getResult(I iface, revokeEntitySharingFromGroups_args args) throws org.apache.thrift.TException {
        revokeEntitySharingFromGroups_result result = new revokeEntitySharingFromGroups_result();
        try {
          result.success = iface.revokeEntitySharingFromGroups(args.domainId, args.entityId, args.groupList, args.permissionTypeId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

    public static class userHasAccess<I extends Iface> extends org.apache.thrift.ProcessFunction<I, userHasAccess_args> {
      public userHasAccess() {
        super("userHasAccess");
      }

      public userHasAccess_args getEmptyArgsInstance() {
        return new userHasAccess_args();
      }

      protected boolean isOneway() {
        return false;
      }

      public userHasAccess_result getResult(I iface, userHasAccess_args args) throws org.apache.thrift.TException {
        userHasAccess_result result = new userHasAccess_result();
        try {
          result.success = iface.userHasAccess(args.domainId, args.userId, args.entityId, args.permissionTypeId);
          result.setSuccessIsSet(true);
        } catch (org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
          result.sre = sre;
        }
        return result;
      }
    }

  }

  public static class AsyncProcessor<I extends AsyncIface> extends org.apache.airavata.base.api.BaseAPI.AsyncProcessor<I> {
    private static final org.slf4j.Logger _LOGGER = org.slf4j.LoggerFactory.getLogger(AsyncProcessor.class.getName());
    public AsyncProcessor(I iface) {
      super(iface, getProcessMap(new java.util.HashMap<java.lang.String, org.apache.thrift.AsyncProcessFunction<I, ? extends org.apache.thrift.TBase, ?>>()));
    }

    protected AsyncProcessor(I iface, java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      super(iface, getProcessMap(processMap));
    }

    private static <I extends AsyncIface> java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase,?>> getProcessMap(java.util.Map<java.lang.String,  org.apache.thrift.AsyncProcessFunction<I, ? extends  org.apache.thrift.TBase, ?>> processMap) {
      processMap.put("createDomain", new createDomain());
      processMap.put("updateDomain", new updateDomain());
      processMap.put("isDomainExists", new isDomainExists());
      processMap.put("deleteDomain", new deleteDomain());
      processMap.put("getDomain", new getDomain());
      processMap.put("getDomains", new getDomains());
      processMap.put("createUser", new createUser());
      processMap.put("updatedUser", new updatedUser());
      processMap.put("isUserExists", new isUserExists());
      processMap.put("deleteUser", new deleteUser());
      processMap.put("getUser", new getUser());
      processMap.put("getUsers", new getUsers());
      processMap.put("createGroup", new createGroup());
      processMap.put("updateGroup", new updateGroup());
      processMap.put("isGroupExists", new isGroupExists());
      processMap.put("deleteGroup", new deleteGroup());
      processMap.put("getGroup", new getGroup());
      processMap.put("getGroups", new getGroups());
      processMap.put("addUsersToGroup", new addUsersToGroup());
      processMap.put("removeUsersFromGroup", new removeUsersFromGroup());
      processMap.put("transferGroupOwnership", new transferGroupOwnership());
      processMap.put("addGroupAdmins", new addGroupAdmins());
      processMap.put("removeGroupAdmins", new removeGroupAdmins());
      processMap.put("hasAdminAccess", new hasAdminAccess());
      processMap.put("hasOwnerAccess", new hasOwnerAccess());
      processMap.put("getGroupMembersOfTypeUser", new getGroupMembersOfTypeUser());
      processMap.put("getGroupMembersOfTypeGroup", new getGroupMembersOfTypeGroup());
      processMap.put("addChildGroupsToParentGroup", new addChildGroupsToParentGroup());
      processMap.put("removeChildGroupFromParentGroup", new removeChildGroupFromParentGroup());
      processMap.put("getAllMemberGroupsForUser", new getAllMemberGroupsForUser());
      processMap.put("createEntityType", new createEntityType());
      processMap.put("updateEntityType", new updateEntityType());
      processMap.put("isEntityTypeExists", new isEntityTypeExists());
      processMap.put("deleteEntityType", new deleteEntityType());
      processMap.put("getEntityType", new getEntityType());
      processMap.put("getEntityTypes", new getEntityTypes());
      processMap.put("createEntity", new createEntity());
      processMap.put("updateEntity", new updateEntity());
      processMap.put("isEntityExists", new isEntityExists());
      processMap.put("deleteEntity", new deleteEntity());
      processMap.put("getEntity", new getEntity());
      processMap.put("searchEntities", new searchEntities());
      processMap.put("getListOfSharedUsers", new getListOfSharedUsers());
      processMap.put("getListOfDirectlySharedUsers", new getListOfDirectlySharedUsers());
      processMap.put("getListOfSharedGroups", new getListOfSharedGroups());
      processMap.put("getListOfDirectlySharedGroups", new getListOfDirectlySharedGroups());
      processMap.put("createPermissionType", new createPermissionType());
      processMap.put("updatePermissionType", new updatePermissionType());
      processMap.put("isPermissionExists", new isPermissionExists());
      processMap.put("deletePermissionType", new deletePermissionType());
      processMap.put("getPermissionType", new getPermissionType());
      processMap.put("getPermissionTypes", new getPermissionTypes());
      processMap.put("shareEntityWithUsers", new shareEntityWithUsers());
      processMap.put("revokeEntitySharingFromUsers", new revokeEntitySharingFromUsers());
      processMap.put("shareEntityWithGroups", new shareEntityWithGroups());
      processMap.put("revokeEntitySharingFromGroups", new revokeEntitySharingFromGroups());
      processMap.put("userHasAccess", new userHasAccess());
      return processMap;
    }

    public static class createDomain<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createDomain_args, java.lang.String> {
      public createDomain() {
        super("createDomain");
      }

      public createDomain_args getEmptyArgsInstance() {
        return new createDomain_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            createDomain_result result = new createDomain_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            createDomain_result result = new createDomain_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.sharing.registry.models.DuplicateEntryException) {
              result.dee = (org.apache.airavata.sharing.registry.models.DuplicateEntryException) e;
              result.setDeeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createDomain_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.createDomain(args.domain,resultHandler);
      }
    }

    public static class updateDomain<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateDomain_args, java.lang.Boolean> {
      public updateDomain() {
        super("updateDomain");
      }

      public updateDomain_args getEmptyArgsInstance() {
        return new updateDomain_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updateDomain_result result = new updateDomain_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updateDomain_result result = new updateDomain_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateDomain_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updateDomain(args.domain,resultHandler);
      }
    }

    public static class isDomainExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isDomainExists_args, java.lang.Boolean> {
      public isDomainExists() {
        super("isDomainExists");
      }

      public isDomainExists_args getEmptyArgsInstance() {
        return new isDomainExists_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isDomainExists_result result = new isDomainExists_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isDomainExists_result result = new isDomainExists_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isDomainExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isDomainExists(args.domainId,resultHandler);
      }
    }

    public static class deleteDomain<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteDomain_args, java.lang.Boolean> {
      public deleteDomain() {
        super("deleteDomain");
      }

      public deleteDomain_args getEmptyArgsInstance() {
        return new deleteDomain_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            deleteDomain_result result = new deleteDomain_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            deleteDomain_result result = new deleteDomain_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteDomain_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.deleteDomain(args.domainId,resultHandler);
      }
    }

    public static class getDomain<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getDomain_args, org.apache.airavata.sharing.registry.models.Domain> {
      public getDomain() {
        super("getDomain");
      }

      public getDomain_args getEmptyArgsInstance() {
        return new getDomain_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Domain> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Domain>() { 
          public void onComplete(org.apache.airavata.sharing.registry.models.Domain o) {
            getDomain_result result = new getDomain_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getDomain_result result = new getDomain_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getDomain_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Domain> resultHandler) throws org.apache.thrift.TException {
        iface.getDomain(args.domainId,resultHandler);
      }
    }

    public static class getDomains<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getDomains_args, java.util.List<org.apache.airavata.sharing.registry.models.Domain>> {
      public getDomains() {
        super("getDomains");
      }

      public getDomains_args getEmptyArgsInstance() {
        return new getDomains_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Domain>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Domain>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.Domain> o) {
            getDomains_result result = new getDomains_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getDomains_result result = new getDomains_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getDomains_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Domain>> resultHandler) throws org.apache.thrift.TException {
        iface.getDomains(args.offset, args.limit,resultHandler);
      }
    }

    public static class createUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createUser_args, java.lang.String> {
      public createUser() {
        super("createUser");
      }

      public createUser_args getEmptyArgsInstance() {
        return new createUser_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            createUser_result result = new createUser_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            createUser_result result = new createUser_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.sharing.registry.models.DuplicateEntryException) {
              result.dee = (org.apache.airavata.sharing.registry.models.DuplicateEntryException) e;
              result.setDeeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createUser_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.createUser(args.user,resultHandler);
      }
    }

    public static class updatedUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updatedUser_args, java.lang.Boolean> {
      public updatedUser() {
        super("updatedUser");
      }

      public updatedUser_args getEmptyArgsInstance() {
        return new updatedUser_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updatedUser_result result = new updatedUser_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updatedUser_result result = new updatedUser_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updatedUser_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updatedUser(args.user,resultHandler);
      }
    }

    public static class isUserExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isUserExists_args, java.lang.Boolean> {
      public isUserExists() {
        super("isUserExists");
      }

      public isUserExists_args getEmptyArgsInstance() {
        return new isUserExists_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isUserExists_result result = new isUserExists_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isUserExists_result result = new isUserExists_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isUserExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isUserExists(args.domainId, args.userId,resultHandler);
      }
    }

    public static class deleteUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteUser_args, java.lang.Boolean> {
      public deleteUser() {
        super("deleteUser");
      }

      public deleteUser_args getEmptyArgsInstance() {
        return new deleteUser_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            deleteUser_result result = new deleteUser_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            deleteUser_result result = new deleteUser_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteUser_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.deleteUser(args.domainId, args.userId,resultHandler);
      }
    }

    public static class getUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUser_args, org.apache.airavata.sharing.registry.models.User> {
      public getUser() {
        super("getUser");
      }

      public getUser_args getEmptyArgsInstance() {
        return new getUser_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.User> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.User>() { 
          public void onComplete(org.apache.airavata.sharing.registry.models.User o) {
            getUser_result result = new getUser_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getUser_result result = new getUser_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getUser_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.User> resultHandler) throws org.apache.thrift.TException {
        iface.getUser(args.domainId, args.userId,resultHandler);
      }
    }

    public static class getUsers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getUsers_args, java.util.List<org.apache.airavata.sharing.registry.models.User>> {
      public getUsers() {
        super("getUsers");
      }

      public getUsers_args getEmptyArgsInstance() {
        return new getUsers_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.User> o) {
            getUsers_result result = new getUsers_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getUsers_result result = new getUsers_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getUsers_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException {
        iface.getUsers(args.domainId, args.offset, args.limit,resultHandler);
      }
    }

    public static class createGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createGroup_args, java.lang.String> {
      public createGroup() {
        super("createGroup");
      }

      public createGroup_args getEmptyArgsInstance() {
        return new createGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            createGroup_result result = new createGroup_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            createGroup_result result = new createGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createGroup_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.createGroup(args.group,resultHandler);
      }
    }

    public static class updateGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateGroup_args, java.lang.Boolean> {
      public updateGroup() {
        super("updateGroup");
      }

      public updateGroup_args getEmptyArgsInstance() {
        return new updateGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updateGroup_result result = new updateGroup_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updateGroup_result result = new updateGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateGroup_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updateGroup(args.group,resultHandler);
      }
    }

    public static class isGroupExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isGroupExists_args, java.lang.Boolean> {
      public isGroupExists() {
        super("isGroupExists");
      }

      public isGroupExists_args getEmptyArgsInstance() {
        return new isGroupExists_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isGroupExists_result result = new isGroupExists_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isGroupExists_result result = new isGroupExists_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isGroupExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isGroupExists(args.domainId, args.groupId,resultHandler);
      }
    }

    public static class deleteGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteGroup_args, java.lang.Boolean> {
      public deleteGroup() {
        super("deleteGroup");
      }

      public deleteGroup_args getEmptyArgsInstance() {
        return new deleteGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            deleteGroup_result result = new deleteGroup_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            deleteGroup_result result = new deleteGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteGroup_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.deleteGroup(args.domainId, args.groupId,resultHandler);
      }
    }

    public static class getGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGroup_args, org.apache.airavata.sharing.registry.models.UserGroup> {
      public getGroup() {
        super("getGroup");
      }

      public getGroup_args getEmptyArgsInstance() {
        return new getGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.UserGroup> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.UserGroup>() { 
          public void onComplete(org.apache.airavata.sharing.registry.models.UserGroup o) {
            getGroup_result result = new getGroup_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getGroup_result result = new getGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGroup_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.UserGroup> resultHandler) throws org.apache.thrift.TException {
        iface.getGroup(args.domainId, args.groupId,resultHandler);
      }
    }

    public static class getGroups<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGroups_args, java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      public getGroups() {
        super("getGroups");
      }

      public getGroups_args getEmptyArgsInstance() {
        return new getGroups_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> o) {
            getGroups_result result = new getGroups_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getGroups_result result = new getGroups_result();
            if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGroups_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
        iface.getGroups(args.domainId, args.offset, args.limit,resultHandler);
      }
    }

    public static class addUsersToGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addUsersToGroup_args, java.lang.Boolean> {
      public addUsersToGroup() {
        super("addUsersToGroup");
      }

      public addUsersToGroup_args getEmptyArgsInstance() {
        return new addUsersToGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            addUsersToGroup_result result = new addUsersToGroup_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            addUsersToGroup_result result = new addUsersToGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addUsersToGroup_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.addUsersToGroup(args.domainId, args.userIds, args.groupId,resultHandler);
      }
    }

    public static class removeUsersFromGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeUsersFromGroup_args, java.lang.Boolean> {
      public removeUsersFromGroup() {
        super("removeUsersFromGroup");
      }

      public removeUsersFromGroup_args getEmptyArgsInstance() {
        return new removeUsersFromGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            removeUsersFromGroup_result result = new removeUsersFromGroup_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            removeUsersFromGroup_result result = new removeUsersFromGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, removeUsersFromGroup_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.removeUsersFromGroup(args.domainId, args.userIds, args.groupId,resultHandler);
      }
    }

    public static class transferGroupOwnership<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, transferGroupOwnership_args, java.lang.Boolean> {
      public transferGroupOwnership() {
        super("transferGroupOwnership");
      }

      public transferGroupOwnership_args getEmptyArgsInstance() {
        return new transferGroupOwnership_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            transferGroupOwnership_result result = new transferGroupOwnership_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            transferGroupOwnership_result result = new transferGroupOwnership_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, transferGroupOwnership_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.transferGroupOwnership(args.domainId, args.groupId, args.newOwnerId,resultHandler);
      }
    }

    public static class addGroupAdmins<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addGroupAdmins_args, java.lang.Boolean> {
      public addGroupAdmins() {
        super("addGroupAdmins");
      }

      public addGroupAdmins_args getEmptyArgsInstance() {
        return new addGroupAdmins_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            addGroupAdmins_result result = new addGroupAdmins_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            addGroupAdmins_result result = new addGroupAdmins_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addGroupAdmins_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.addGroupAdmins(args.domainId, args.groupId, args.adminIds,resultHandler);
      }
    }

    public static class removeGroupAdmins<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeGroupAdmins_args, java.lang.Boolean> {
      public removeGroupAdmins() {
        super("removeGroupAdmins");
      }

      public removeGroupAdmins_args getEmptyArgsInstance() {
        return new removeGroupAdmins_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            removeGroupAdmins_result result = new removeGroupAdmins_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            removeGroupAdmins_result result = new removeGroupAdmins_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, removeGroupAdmins_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.removeGroupAdmins(args.domainId, args.groupId, args.adminIds,resultHandler);
      }
    }

    public static class hasAdminAccess<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasAdminAccess_args, java.lang.Boolean> {
      public hasAdminAccess() {
        super("hasAdminAccess");
      }

      public hasAdminAccess_args getEmptyArgsInstance() {
        return new hasAdminAccess_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            hasAdminAccess_result result = new hasAdminAccess_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            hasAdminAccess_result result = new hasAdminAccess_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, hasAdminAccess_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.hasAdminAccess(args.domainId, args.groupId, args.adminId,resultHandler);
      }
    }

    public static class hasOwnerAccess<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, hasOwnerAccess_args, java.lang.Boolean> {
      public hasOwnerAccess() {
        super("hasOwnerAccess");
      }

      public hasOwnerAccess_args getEmptyArgsInstance() {
        return new hasOwnerAccess_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            hasOwnerAccess_result result = new hasOwnerAccess_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            hasOwnerAccess_result result = new hasOwnerAccess_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, hasOwnerAccess_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.hasOwnerAccess(args.domainId, args.groupId, args.ownerId,resultHandler);
      }
    }

    public static class getGroupMembersOfTypeUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGroupMembersOfTypeUser_args, java.util.List<org.apache.airavata.sharing.registry.models.User>> {
      public getGroupMembersOfTypeUser() {
        super("getGroupMembersOfTypeUser");
      }

      public getGroupMembersOfTypeUser_args getEmptyArgsInstance() {
        return new getGroupMembersOfTypeUser_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.User> o) {
            getGroupMembersOfTypeUser_result result = new getGroupMembersOfTypeUser_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getGroupMembersOfTypeUser_result result = new getGroupMembersOfTypeUser_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGroupMembersOfTypeUser_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException {
        iface.getGroupMembersOfTypeUser(args.domainId, args.groupId, args.offset, args.limit,resultHandler);
      }
    }

    public static class getGroupMembersOfTypeGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getGroupMembersOfTypeGroup_args, java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      public getGroupMembersOfTypeGroup() {
        super("getGroupMembersOfTypeGroup");
      }

      public getGroupMembersOfTypeGroup_args getEmptyArgsInstance() {
        return new getGroupMembersOfTypeGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> o) {
            getGroupMembersOfTypeGroup_result result = new getGroupMembersOfTypeGroup_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getGroupMembersOfTypeGroup_result result = new getGroupMembersOfTypeGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getGroupMembersOfTypeGroup_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
        iface.getGroupMembersOfTypeGroup(args.domainId, args.groupId, args.offset, args.limit,resultHandler);
      }
    }

    public static class addChildGroupsToParentGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, addChildGroupsToParentGroup_args, java.lang.Boolean> {
      public addChildGroupsToParentGroup() {
        super("addChildGroupsToParentGroup");
      }

      public addChildGroupsToParentGroup_args getEmptyArgsInstance() {
        return new addChildGroupsToParentGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            addChildGroupsToParentGroup_result result = new addChildGroupsToParentGroup_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            addChildGroupsToParentGroup_result result = new addChildGroupsToParentGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, addChildGroupsToParentGroup_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.addChildGroupsToParentGroup(args.domainId, args.childIds, args.groupId,resultHandler);
      }
    }

    public static class removeChildGroupFromParentGroup<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, removeChildGroupFromParentGroup_args, java.lang.Boolean> {
      public removeChildGroupFromParentGroup() {
        super("removeChildGroupFromParentGroup");
      }

      public removeChildGroupFromParentGroup_args getEmptyArgsInstance() {
        return new removeChildGroupFromParentGroup_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            removeChildGroupFromParentGroup_result result = new removeChildGroupFromParentGroup_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            removeChildGroupFromParentGroup_result result = new removeChildGroupFromParentGroup_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, removeChildGroupFromParentGroup_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.removeChildGroupFromParentGroup(args.domainId, args.childId, args.groupId,resultHandler);
      }
    }

    public static class getAllMemberGroupsForUser<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getAllMemberGroupsForUser_args, java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      public getAllMemberGroupsForUser() {
        super("getAllMemberGroupsForUser");
      }

      public getAllMemberGroupsForUser_args getEmptyArgsInstance() {
        return new getAllMemberGroupsForUser_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> o) {
            getAllMemberGroupsForUser_result result = new getAllMemberGroupsForUser_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getAllMemberGroupsForUser_result result = new getAllMemberGroupsForUser_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getAllMemberGroupsForUser_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
        iface.getAllMemberGroupsForUser(args.domainId, args.userId,resultHandler);
      }
    }

    public static class createEntityType<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createEntityType_args, java.lang.String> {
      public createEntityType() {
        super("createEntityType");
      }

      public createEntityType_args getEmptyArgsInstance() {
        return new createEntityType_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            createEntityType_result result = new createEntityType_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            createEntityType_result result = new createEntityType_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.sharing.registry.models.DuplicateEntryException) {
              result.dee = (org.apache.airavata.sharing.registry.models.DuplicateEntryException) e;
              result.setDeeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createEntityType_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.createEntityType(args.entityType,resultHandler);
      }
    }

    public static class updateEntityType<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateEntityType_args, java.lang.Boolean> {
      public updateEntityType() {
        super("updateEntityType");
      }

      public updateEntityType_args getEmptyArgsInstance() {
        return new updateEntityType_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updateEntityType_result result = new updateEntityType_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updateEntityType_result result = new updateEntityType_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateEntityType_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updateEntityType(args.entityType,resultHandler);
      }
    }

    public static class isEntityTypeExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isEntityTypeExists_args, java.lang.Boolean> {
      public isEntityTypeExists() {
        super("isEntityTypeExists");
      }

      public isEntityTypeExists_args getEmptyArgsInstance() {
        return new isEntityTypeExists_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isEntityTypeExists_result result = new isEntityTypeExists_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isEntityTypeExists_result result = new isEntityTypeExists_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isEntityTypeExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isEntityTypeExists(args.domainId, args.entityTypeId,resultHandler);
      }
    }

    public static class deleteEntityType<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteEntityType_args, java.lang.Boolean> {
      public deleteEntityType() {
        super("deleteEntityType");
      }

      public deleteEntityType_args getEmptyArgsInstance() {
        return new deleteEntityType_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            deleteEntityType_result result = new deleteEntityType_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            deleteEntityType_result result = new deleteEntityType_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteEntityType_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.deleteEntityType(args.domainId, args.entityTypeId,resultHandler);
      }
    }

    public static class getEntityType<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getEntityType_args, org.apache.airavata.sharing.registry.models.EntityType> {
      public getEntityType() {
        super("getEntityType");
      }

      public getEntityType_args getEmptyArgsInstance() {
        return new getEntityType_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.EntityType> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.EntityType>() { 
          public void onComplete(org.apache.airavata.sharing.registry.models.EntityType o) {
            getEntityType_result result = new getEntityType_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getEntityType_result result = new getEntityType_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getEntityType_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.EntityType> resultHandler) throws org.apache.thrift.TException {
        iface.getEntityType(args.domainId, args.entityTypeId,resultHandler);
      }
    }

    public static class getEntityTypes<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getEntityTypes_args, java.util.List<org.apache.airavata.sharing.registry.models.EntityType>> {
      public getEntityTypes() {
        super("getEntityTypes");
      }

      public getEntityTypes_args getEmptyArgsInstance() {
        return new getEntityTypes_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.EntityType>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.EntityType>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.EntityType> o) {
            getEntityTypes_result result = new getEntityTypes_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getEntityTypes_result result = new getEntityTypes_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getEntityTypes_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.EntityType>> resultHandler) throws org.apache.thrift.TException {
        iface.getEntityTypes(args.domainId, args.offset, args.limit,resultHandler);
      }
    }

    public static class createEntity<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createEntity_args, java.lang.String> {
      public createEntity() {
        super("createEntity");
      }

      public createEntity_args getEmptyArgsInstance() {
        return new createEntity_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            createEntity_result result = new createEntity_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            createEntity_result result = new createEntity_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createEntity_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.createEntity(args.entity,resultHandler);
      }
    }

    public static class updateEntity<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updateEntity_args, java.lang.Boolean> {
      public updateEntity() {
        super("updateEntity");
      }

      public updateEntity_args getEmptyArgsInstance() {
        return new updateEntity_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updateEntity_result result = new updateEntity_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updateEntity_result result = new updateEntity_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updateEntity_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updateEntity(args.entity,resultHandler);
      }
    }

    public static class isEntityExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isEntityExists_args, java.lang.Boolean> {
      public isEntityExists() {
        super("isEntityExists");
      }

      public isEntityExists_args getEmptyArgsInstance() {
        return new isEntityExists_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isEntityExists_result result = new isEntityExists_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isEntityExists_result result = new isEntityExists_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isEntityExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isEntityExists(args.domainId, args.entityId,resultHandler);
      }
    }

    public static class deleteEntity<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deleteEntity_args, java.lang.Boolean> {
      public deleteEntity() {
        super("deleteEntity");
      }

      public deleteEntity_args getEmptyArgsInstance() {
        return new deleteEntity_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            deleteEntity_result result = new deleteEntity_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            deleteEntity_result result = new deleteEntity_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deleteEntity_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.deleteEntity(args.domainId, args.entityId,resultHandler);
      }
    }

    public static class getEntity<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getEntity_args, org.apache.airavata.sharing.registry.models.Entity> {
      public getEntity() {
        super("getEntity");
      }

      public getEntity_args getEmptyArgsInstance() {
        return new getEntity_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Entity> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Entity>() { 
          public void onComplete(org.apache.airavata.sharing.registry.models.Entity o) {
            getEntity_result result = new getEntity_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getEntity_result result = new getEntity_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getEntity_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.Entity> resultHandler) throws org.apache.thrift.TException {
        iface.getEntity(args.domainId, args.entityId,resultHandler);
      }
    }

    public static class searchEntities<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, searchEntities_args, java.util.List<org.apache.airavata.sharing.registry.models.Entity>> {
      public searchEntities() {
        super("searchEntities");
      }

      public searchEntities_args getEmptyArgsInstance() {
        return new searchEntities_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Entity>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Entity>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.Entity> o) {
            searchEntities_result result = new searchEntities_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            searchEntities_result result = new searchEntities_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, searchEntities_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.Entity>> resultHandler) throws org.apache.thrift.TException {
        iface.searchEntities(args.domainId, args.userId, args.filters, args.offset, args.limit,resultHandler);
      }
    }

    public static class getListOfSharedUsers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getListOfSharedUsers_args, java.util.List<org.apache.airavata.sharing.registry.models.User>> {
      public getListOfSharedUsers() {
        super("getListOfSharedUsers");
      }

      public getListOfSharedUsers_args getEmptyArgsInstance() {
        return new getListOfSharedUsers_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.User> o) {
            getListOfSharedUsers_result result = new getListOfSharedUsers_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getListOfSharedUsers_result result = new getListOfSharedUsers_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getListOfSharedUsers_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException {
        iface.getListOfSharedUsers(args.domainId, args.entityId, args.permissionTypeId,resultHandler);
      }
    }

    public static class getListOfDirectlySharedUsers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getListOfDirectlySharedUsers_args, java.util.List<org.apache.airavata.sharing.registry.models.User>> {
      public getListOfDirectlySharedUsers() {
        super("getListOfDirectlySharedUsers");
      }

      public getListOfDirectlySharedUsers_args getEmptyArgsInstance() {
        return new getListOfDirectlySharedUsers_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.User> o) {
            getListOfDirectlySharedUsers_result result = new getListOfDirectlySharedUsers_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getListOfDirectlySharedUsers_result result = new getListOfDirectlySharedUsers_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getListOfDirectlySharedUsers_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.User>> resultHandler) throws org.apache.thrift.TException {
        iface.getListOfDirectlySharedUsers(args.domainId, args.entityId, args.permissionTypeId,resultHandler);
      }
    }

    public static class getListOfSharedGroups<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getListOfSharedGroups_args, java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      public getListOfSharedGroups() {
        super("getListOfSharedGroups");
      }

      public getListOfSharedGroups_args getEmptyArgsInstance() {
        return new getListOfSharedGroups_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> o) {
            getListOfSharedGroups_result result = new getListOfSharedGroups_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getListOfSharedGroups_result result = new getListOfSharedGroups_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getListOfSharedGroups_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
        iface.getListOfSharedGroups(args.domainId, args.entityId, args.permissionTypeId,resultHandler);
      }
    }

    public static class getListOfDirectlySharedGroups<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getListOfDirectlySharedGroups_args, java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> {
      public getListOfDirectlySharedGroups() {
        super("getListOfDirectlySharedGroups");
      }

      public getListOfDirectlySharedGroups_args getEmptyArgsInstance() {
        return new getListOfDirectlySharedGroups_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> o) {
            getListOfDirectlySharedGroups_result result = new getListOfDirectlySharedGroups_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getListOfDirectlySharedGroups_result result = new getListOfDirectlySharedGroups_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getListOfDirectlySharedGroups_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>> resultHandler) throws org.apache.thrift.TException {
        iface.getListOfDirectlySharedGroups(args.domainId, args.entityId, args.permissionTypeId,resultHandler);
      }
    }

    public static class createPermissionType<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, createPermissionType_args, java.lang.String> {
      public createPermissionType() {
        super("createPermissionType");
      }

      public createPermissionType_args getEmptyArgsInstance() {
        return new createPermissionType_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.String> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.String>() { 
          public void onComplete(java.lang.String o) {
            createPermissionType_result result = new createPermissionType_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            createPermissionType_result result = new createPermissionType_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.airavata.sharing.registry.models.DuplicateEntryException) {
              result.dee = (org.apache.airavata.sharing.registry.models.DuplicateEntryException) e;
              result.setDeeIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, createPermissionType_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.String> resultHandler) throws org.apache.thrift.TException {
        iface.createPermissionType(args.permissionType,resultHandler);
      }
    }

    public static class updatePermissionType<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, updatePermissionType_args, java.lang.Boolean> {
      public updatePermissionType() {
        super("updatePermissionType");
      }

      public updatePermissionType_args getEmptyArgsInstance() {
        return new updatePermissionType_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            updatePermissionType_result result = new updatePermissionType_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            updatePermissionType_result result = new updatePermissionType_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, updatePermissionType_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.updatePermissionType(args.permissionType,resultHandler);
      }
    }

    public static class isPermissionExists<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, isPermissionExists_args, java.lang.Boolean> {
      public isPermissionExists() {
        super("isPermissionExists");
      }

      public isPermissionExists_args getEmptyArgsInstance() {
        return new isPermissionExists_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            isPermissionExists_result result = new isPermissionExists_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            isPermissionExists_result result = new isPermissionExists_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, isPermissionExists_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.isPermissionExists(args.dimainId, args.permissionId,resultHandler);
      }
    }

    public static class deletePermissionType<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, deletePermissionType_args, java.lang.Boolean> {
      public deletePermissionType() {
        super("deletePermissionType");
      }

      public deletePermissionType_args getEmptyArgsInstance() {
        return new deletePermissionType_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            deletePermissionType_result result = new deletePermissionType_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            deletePermissionType_result result = new deletePermissionType_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, deletePermissionType_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.deletePermissionType(args.domainId, args.permissionTypeId,resultHandler);
      }
    }

    public static class getPermissionType<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getPermissionType_args, org.apache.airavata.sharing.registry.models.PermissionType> {
      public getPermissionType() {
        super("getPermissionType");
      }

      public getPermissionType_args getEmptyArgsInstance() {
        return new getPermissionType_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.PermissionType> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.PermissionType>() { 
          public void onComplete(org.apache.airavata.sharing.registry.models.PermissionType o) {
            getPermissionType_result result = new getPermissionType_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getPermissionType_result result = new getPermissionType_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getPermissionType_args args, org.apache.thrift.async.AsyncMethodCallback<org.apache.airavata.sharing.registry.models.PermissionType> resultHandler) throws org.apache.thrift.TException {
        iface.getPermissionType(args.domainId, args.permissionTypeId,resultHandler);
      }
    }

    public static class getPermissionTypes<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, getPermissionTypes_args, java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>> {
      public getPermissionTypes() {
        super("getPermissionTypes");
      }

      public getPermissionTypes_args getEmptyArgsInstance() {
        return new getPermissionTypes_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>>() { 
          public void onComplete(java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> o) {
            getPermissionTypes_result result = new getPermissionTypes_result();
            result.success = o;
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            getPermissionTypes_result result = new getPermissionTypes_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, getPermissionTypes_args args, org.apache.thrift.async.AsyncMethodCallback<java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>> resultHandler) throws org.apache.thrift.TException {
        iface.getPermissionTypes(args.domainId, args.offset, args.limit,resultHandler);
      }
    }

    public static class shareEntityWithUsers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, shareEntityWithUsers_args, java.lang.Boolean> {
      public shareEntityWithUsers() {
        super("shareEntityWithUsers");
      }

      public shareEntityWithUsers_args getEmptyArgsInstance() {
        return new shareEntityWithUsers_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            shareEntityWithUsers_result result = new shareEntityWithUsers_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            shareEntityWithUsers_result result = new shareEntityWithUsers_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, shareEntityWithUsers_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.shareEntityWithUsers(args.domainId, args.entityId, args.userList, args.permissionTypeId, args.cascadePermission,resultHandler);
      }
    }

    public static class revokeEntitySharingFromUsers<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, revokeEntitySharingFromUsers_args, java.lang.Boolean> {
      public revokeEntitySharingFromUsers() {
        super("revokeEntitySharingFromUsers");
      }

      public revokeEntitySharingFromUsers_args getEmptyArgsInstance() {
        return new revokeEntitySharingFromUsers_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            revokeEntitySharingFromUsers_result result = new revokeEntitySharingFromUsers_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            revokeEntitySharingFromUsers_result result = new revokeEntitySharingFromUsers_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, revokeEntitySharingFromUsers_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.revokeEntitySharingFromUsers(args.domainId, args.entityId, args.userList, args.permissionTypeId,resultHandler);
      }
    }

    public static class shareEntityWithGroups<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, shareEntityWithGroups_args, java.lang.Boolean> {
      public shareEntityWithGroups() {
        super("shareEntityWithGroups");
      }

      public shareEntityWithGroups_args getEmptyArgsInstance() {
        return new shareEntityWithGroups_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            shareEntityWithGroups_result result = new shareEntityWithGroups_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            shareEntityWithGroups_result result = new shareEntityWithGroups_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, shareEntityWithGroups_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.shareEntityWithGroups(args.domainId, args.entityId, args.groupList, args.permissionTypeId, args.cascadePermission,resultHandler);
      }
    }

    public static class revokeEntitySharingFromGroups<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, revokeEntitySharingFromGroups_args, java.lang.Boolean> {
      public revokeEntitySharingFromGroups() {
        super("revokeEntitySharingFromGroups");
      }

      public revokeEntitySharingFromGroups_args getEmptyArgsInstance() {
        return new revokeEntitySharingFromGroups_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            revokeEntitySharingFromGroups_result result = new revokeEntitySharingFromGroups_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            revokeEntitySharingFromGroups_result result = new revokeEntitySharingFromGroups_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, revokeEntitySharingFromGroups_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.revokeEntitySharingFromGroups(args.domainId, args.entityId, args.groupList, args.permissionTypeId,resultHandler);
      }
    }

    public static class userHasAccess<I extends AsyncIface> extends org.apache.thrift.AsyncProcessFunction<I, userHasAccess_args, java.lang.Boolean> {
      public userHasAccess() {
        super("userHasAccess");
      }

      public userHasAccess_args getEmptyArgsInstance() {
        return new userHasAccess_args();
      }

      public org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> getResultHandler(final org.apache.thrift.server.AbstractNonblockingServer.AsyncFrameBuffer fb, final int seqid) {
        final org.apache.thrift.AsyncProcessFunction fcall = this;
        return new org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean>() { 
          public void onComplete(java.lang.Boolean o) {
            userHasAccess_result result = new userHasAccess_result();
            result.success = o;
            result.setSuccessIsSet(true);
            try {
              fcall.sendResponse(fb, result, org.apache.thrift.protocol.TMessageType.REPLY,seqid);
            } catch (org.apache.thrift.transport.TTransportException e) {
              _LOGGER.error("TTransportException writing to internal frame buffer", e);
              fb.close();
            } catch (java.lang.Exception e) {
              _LOGGER.error("Exception writing to internal frame buffer", e);
              onError(e);
            }
          }
          public void onError(java.lang.Exception e) {
            byte msgType = org.apache.thrift.protocol.TMessageType.REPLY;
            org.apache.thrift.TSerializable msg;
            userHasAccess_result result = new userHasAccess_result();
            if (e instanceof org.apache.airavata.sharing.registry.models.SharingRegistryException) {
              result.sre = (org.apache.airavata.sharing.registry.models.SharingRegistryException) e;
              result.setSreIsSet(true);
              msg = result;
            } else if (e instanceof org.apache.thrift.transport.TTransportException) {
              _LOGGER.error("TTransportException inside handler", e);
              fb.close();
              return;
            } else if (e instanceof org.apache.thrift.TApplicationException) {
              _LOGGER.error("TApplicationException inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = (org.apache.thrift.TApplicationException)e;
            } else {
              _LOGGER.error("Exception inside handler", e);
              msgType = org.apache.thrift.protocol.TMessageType.EXCEPTION;
              msg = new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.INTERNAL_ERROR, e.getMessage());
            }
            try {
              fcall.sendResponse(fb,msg,msgType,seqid);
            } catch (java.lang.Exception ex) {
              _LOGGER.error("Exception writing to internal frame buffer", ex);
              fb.close();
            }
          }
        };
      }

      protected boolean isOneway() {
        return false;
      }

      public void start(I iface, userHasAccess_args args, org.apache.thrift.async.AsyncMethodCallback<java.lang.Boolean> resultHandler) throws org.apache.thrift.TException {
        iface.userHasAccess(args.domainId, args.userId, args.entityId, args.permissionTypeId,resultHandler);
      }
    }

  }

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

    private static final org.apache.thrift.protocol.TField DOMAIN_FIELD_DESC = new org.apache.thrift.protocol.TField("domain", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.sharing.registry.models.Domain domain; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN((short)1, "domain");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN
            return DOMAIN;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN, new org.apache.thrift.meta_data.FieldMetaData("domain", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.Domain.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createDomain_args.class, metaDataMap);
    }

    public createDomain_args() {
    }

    public createDomain_args(
      org.apache.airavata.sharing.registry.models.Domain domain)
    {
      this();
      this.domain = domain;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createDomain_args(createDomain_args other) {
      if (other.isSetDomain()) {
        this.domain = new org.apache.airavata.sharing.registry.models.Domain(other.domain);
      }
    }

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

    @Override
    public void clear() {
      this.domain = null;
    }

    public org.apache.airavata.sharing.registry.models.Domain getDomain() {
      return this.domain;
    }

    public createDomain_args setDomain(org.apache.airavata.sharing.registry.models.Domain domain) {
      this.domain = domain;
      return this;
    }

    public void unsetDomain() {
      this.domain = null;
    }

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

    public void setDomainIsSet(boolean value) {
      if (!value) {
        this.domain = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN:
        if (value == null) {
          unsetDomain();
        } else {
          setDomain((org.apache.airavata.sharing.registry.models.Domain)value);
        }
        break;

      }
    }

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

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

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

      switch (field) {
      case DOMAIN:
        return isSetDomain();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_domain = true && this.isSetDomain();
      boolean that_present_domain = true && that.isSetDomain();
      if (this_present_domain || that_present_domain) {
        if (!(this_present_domain && that_present_domain))
          return false;
        if (!this.domain.equals(that.domain))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetDomain()) ? 131071 : 524287);
      if (isSetDomain())
        hashCode = hashCode * 8191 + domain.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomain()).compareTo(other.isSetDomain());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomain()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domain, other.domain);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domain:");
      if (this.domain == null) {
        sb.append("null");
      } else {
        sb.append(this.domain);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domain == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domain' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (domain != null) {
        domain.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, java.lang.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 createDomain_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createDomain_argsStandardScheme getScheme() {
        return new createDomain_argsStandardScheme();
      }
    }

    private static class createDomain_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createDomain_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createDomain_args 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: // DOMAIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.domain = new org.apache.airavata.sharing.registry.models.Domain();
                struct.domain.read(iprot);
                struct.setDomainIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createDomain_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domain != null) {
          oprot.writeFieldBegin(DOMAIN_FIELD_DESC);
          struct.domain.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class createDomain_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createDomain_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createDomain_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domain.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createDomain_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domain = new org.apache.airavata.sharing.registry.models.Domain();
        struct.domain.read(iprot);
        struct.setDomainIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField DEE_FIELD_DESC = new org.apache.thrift.protocol.TField("dee", org.apache.thrift.protocol.TType.STRUCT, (short)2);

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

    public java.lang.String success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required
    public org.apache.airavata.sharing.registry.models.DuplicateEntryException dee; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre"),
      DEE((short)2, "dee");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          case 2: // DEE
            return DEE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      tmpMap.put(_Fields.DEE, new org.apache.thrift.meta_data.FieldMetaData("dee", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.DuplicateEntryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createDomain_result.class, metaDataMap);
    }

    public createDomain_result() {
    }

    public createDomain_result(
      java.lang.String success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre,
      org.apache.airavata.sharing.registry.models.DuplicateEntryException dee)
    {
      this();
      this.success = success;
      this.sre = sre;
      this.dee = dee;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createDomain_result(createDomain_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
      if (other.isSetDee()) {
        this.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException(other.dee);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
      this.dee = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createDomain_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public createDomain_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.DuplicateEntryException getDee() {
      return this.dee;
    }

    public createDomain_result setDee(org.apache.airavata.sharing.registry.models.DuplicateEntryException dee) {
      this.dee = dee;
      return this;
    }

    public void unsetDee() {
      this.dee = null;
    }

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

    public void setDeeIsSet(boolean value) {
      if (!value) {
        this.dee = null;
      }
    }

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

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      case DEE:
        if (value == null) {
          unsetDee();
        } else {
          setDee((org.apache.airavata.sharing.registry.models.DuplicateEntryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

      case DEE:
        return getDee();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      case DEE:
        return isSetDee();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      boolean this_present_dee = true && this.isSetDee();
      boolean that_present_dee = true && that.isSetDee();
      if (this_present_dee || that_present_dee) {
        if (!(this_present_dee && that_present_dee))
          return false;
        if (!this.dee.equals(that.dee))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      hashCode = hashCode * 8191 + ((isSetDee()) ? 131071 : 524287);
      if (isSetDee())
        hashCode = hashCode * 8191 + dee.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetDee()).compareTo(other.isSetDee());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDee()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dee, other.dee);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("dee:");
      if (this.dee == null) {
        sb.append("null");
      } else {
        sb.append(this.dee);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 createDomain_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createDomain_resultStandardScheme getScheme() {
        return new createDomain_resultStandardScheme();
      }
    }

    private static class createDomain_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createDomain_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createDomain_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // DEE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException();
                struct.dee.read(iprot);
                struct.setDeeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createDomain_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.dee != null) {
          oprot.writeFieldBegin(DEE_FIELD_DESC);
          struct.dee.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class createDomain_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createDomain_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createDomain_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        if (struct.isSetDee()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
        if (struct.isSetDee()) {
          struct.dee.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createDomain_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException();
          struct.dee.read(iprot);
          struct.setDeeIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField DOMAIN_FIELD_DESC = new org.apache.thrift.protocol.TField("domain", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.sharing.registry.models.Domain domain; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN((short)1, "domain");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN
            return DOMAIN;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN, new org.apache.thrift.meta_data.FieldMetaData("domain", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.Domain.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateDomain_args.class, metaDataMap);
    }

    public updateDomain_args() {
    }

    public updateDomain_args(
      org.apache.airavata.sharing.registry.models.Domain domain)
    {
      this();
      this.domain = domain;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateDomain_args(updateDomain_args other) {
      if (other.isSetDomain()) {
        this.domain = new org.apache.airavata.sharing.registry.models.Domain(other.domain);
      }
    }

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

    @Override
    public void clear() {
      this.domain = null;
    }

    public org.apache.airavata.sharing.registry.models.Domain getDomain() {
      return this.domain;
    }

    public updateDomain_args setDomain(org.apache.airavata.sharing.registry.models.Domain domain) {
      this.domain = domain;
      return this;
    }

    public void unsetDomain() {
      this.domain = null;
    }

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

    public void setDomainIsSet(boolean value) {
      if (!value) {
        this.domain = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN:
        if (value == null) {
          unsetDomain();
        } else {
          setDomain((org.apache.airavata.sharing.registry.models.Domain)value);
        }
        break;

      }
    }

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

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

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

      switch (field) {
      case DOMAIN:
        return isSetDomain();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_domain = true && this.isSetDomain();
      boolean that_present_domain = true && that.isSetDomain();
      if (this_present_domain || that_present_domain) {
        if (!(this_present_domain && that_present_domain))
          return false;
        if (!this.domain.equals(that.domain))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetDomain()) ? 131071 : 524287);
      if (isSetDomain())
        hashCode = hashCode * 8191 + domain.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomain()).compareTo(other.isSetDomain());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomain()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domain, other.domain);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domain:");
      if (this.domain == null) {
        sb.append("null");
      } else {
        sb.append(this.domain);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domain == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domain' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (domain != null) {
        domain.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, java.lang.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 updateDomain_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateDomain_argsStandardScheme getScheme() {
        return new updateDomain_argsStandardScheme();
      }
    }

    private static class updateDomain_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateDomain_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateDomain_args 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: // DOMAIN
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.domain = new org.apache.airavata.sharing.registry.models.Domain();
                struct.domain.read(iprot);
                struct.setDomainIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateDomain_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domain != null) {
          oprot.writeFieldBegin(DOMAIN_FIELD_DESC);
          struct.domain.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateDomain_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateDomain_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateDomain_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domain.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateDomain_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domain = new org.apache.airavata.sharing.registry.models.Domain();
        struct.domain.read(iprot);
        struct.setDomainIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateDomain_result.class, metaDataMap);
    }

    public updateDomain_result() {
    }

    public updateDomain_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateDomain_result(updateDomain_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateDomain_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public updateDomain_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

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

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

    private static class updateDomain_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateDomain_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateDomain_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateDomain_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateDomain_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateDomain_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateDomain_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateDomain_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String domainId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isDomainExists_args.class, metaDataMap);
    }

    public isDomainExists_args() {
    }

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

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isDomainExists_args(isDomainExists_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
    }

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

    @Override
    public void clear() {
      this.domainId = null;
    }

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

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

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

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

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

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

      }
    }

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

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

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

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

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

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 isDomainExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isDomainExists_argsStandardScheme getScheme() {
        return new isDomainExists_argsStandardScheme();
      }
    }

    private static class isDomainExists_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isDomainExists_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isDomainExists_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isDomainExists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isDomainExists_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isDomainExists_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isDomainExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isDomainExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isDomainExists_result.class, metaDataMap);
    }

    public isDomainExists_result() {
    }

    public isDomainExists_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isDomainExists_result(isDomainExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isDomainExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public isDomainExists_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

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

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

    private static class isDomainExists_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isDomainExists_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isDomainExists_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isDomainExists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isDomainExists_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isDomainExists_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isDomainExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isDomainExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String domainId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteDomain_args.class, metaDataMap);
    }

    public deleteDomain_args() {
    }

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

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteDomain_args(deleteDomain_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
    }

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

    @Override
    public void clear() {
      this.domainId = null;
    }

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

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

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

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

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

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

      }
    }

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

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

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

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

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

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 deleteDomain_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteDomain_argsStandardScheme getScheme() {
        return new deleteDomain_argsStandardScheme();
      }
    }

    private static class deleteDomain_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteDomain_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteDomain_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteDomain_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class deleteDomain_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteDomain_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteDomain_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteDomain_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteDomain_result.class, metaDataMap);
    }

    public deleteDomain_result() {
    }

    public deleteDomain_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteDomain_result(deleteDomain_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteDomain_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public deleteDomain_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

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

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

    private static class deleteDomain_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteDomain_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteDomain_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteDomain_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class deleteDomain_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteDomain_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteDomain_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteDomain_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);

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

    public java.lang.String domainId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDomain_args.class, metaDataMap);
    }

    public getDomain_args() {
    }

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

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getDomain_args(getDomain_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
    }

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

    @Override
    public void clear() {
      this.domainId = null;
    }

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

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

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

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

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

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

      }
    }

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

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

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

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

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

      return true;
    }

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

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

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getDomain_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getDomain_argsStandardScheme getScheme() {
        return new getDomain_argsStandardScheme();
      }
    }

    private static class getDomain_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getDomain_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getDomain_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getDomain_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getDomain_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getDomain_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getDomain_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getDomain_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.sharing.registry.models.Domain success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.Domain.class)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDomain_result.class, metaDataMap);
    }

    public getDomain_result() {
    }

    public getDomain_result(
      org.apache.airavata.sharing.registry.models.Domain success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getDomain_result(getDomain_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.sharing.registry.models.Domain(other.success);
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public org.apache.airavata.sharing.registry.models.Domain getSuccess() {
      return this.success;
    }

    public getDomain_result setSuccess(org.apache.airavata.sharing.registry.models.Domain success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getDomain_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.sharing.registry.models.Domain)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.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, java.lang.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 getDomain_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getDomain_resultStandardScheme getScheme() {
        return new getDomain_resultStandardScheme();
      }
    }

    private static class getDomain_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getDomain_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getDomain_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.sharing.registry.models.Domain();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getDomain_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getDomain_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getDomain_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getDomain_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getDomain_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.sharing.registry.models.Domain();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)1);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)2);

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

    public int offset; // required
    public int limit; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      OFFSET((short)1, "offset"),
      LIMIT((short)2, "limit");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // OFFSET
            return OFFSET;
          case 2: // LIMIT
            return LIMIT;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    private static final int __OFFSET_ISSET_ID = 0;
    private static final int __LIMIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDomains_args.class, metaDataMap);
    }

    public getDomains_args() {
    }

    public getDomains_args(
      int offset,
      int limit)
    {
      this();
      this.offset = offset;
      setOffsetIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getDomains_args(getDomains_args other) {
      __isset_bitfield = other.__isset_bitfield;
      this.offset = other.offset;
      this.limit = other.limit;
    }

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

    @Override
    public void clear() {
      setOffsetIsSet(false);
      this.offset = 0;
      setLimitIsSet(false);
      this.limit = 0;
    }

    public int getOffset() {
      return this.offset;
    }

    public getDomains_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

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

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

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

    public int getLimit() {
      return this.limit;
    }

    public getDomains_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

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

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

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

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((java.lang.Integer)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((java.lang.Integer)value);
        }
        break;

      }
    }

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

      case LIMIT:
        return getLimit();

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

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

      switch (field) {
      case OFFSET:
        return isSetOffset();
      case LIMIT:
        return isSetLimit();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + offset;

      hashCode = hashCode * 8191 + limit;

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("offset:");
      sb.append(this.offset);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

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

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

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

    private static class getDomains_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getDomains_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getDomains_args 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: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getDomains_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getDomains_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getDomains_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getDomains_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeI32(struct.offset);
        oprot.writeI32(struct.limit);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getDomains_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public java.util.List<org.apache.airavata.sharing.registry.models.Domain> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.Domain.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getDomains_result.class, metaDataMap);
    }

    public getDomains_result() {
    }

    public getDomains_result(
      java.util.List<org.apache.airavata.sharing.registry.models.Domain> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getDomains_result(getDomains_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.Domain> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.Domain>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.Domain other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.Domain(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

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

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.Domain> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.Domain elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.Domain>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.Domain> getSuccess() {
      return this.success;
    }

    public getDomains_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.Domain> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getDomains_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.Domain>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getDomains_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getDomains_resultStandardScheme getScheme() {
        return new getDomains_resultStandardScheme();
      }
    }

    private static class getDomains_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getDomains_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getDomains_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.Domain>(_list0.size);
                  org.apache.airavata.sharing.registry.models.Domain _elem1;
                  for (int _i2 = 0; _i2 < _list0.size; ++_i2)
                  {
                    _elem1 = new org.apache.airavata.sharing.registry.models.Domain();
                    _elem1.read(iprot);
                    struct.success.add(_elem1);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getDomains_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.Domain _iter3 : struct.success)
            {
              _iter3.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getDomains_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getDomains_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getDomains_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.Domain _iter4 : struct.success)
            {
              _iter4.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getDomains_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.Domain>(_list5.size);
            org.apache.airavata.sharing.registry.models.Domain _elem6;
            for (int _i7 = 0; _i7 < _list5.size; ++_i7)
            {
              _elem6 = new org.apache.airavata.sharing.registry.models.Domain();
              _elem6.read(iprot);
              struct.success.add(_elem6);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.sharing.registry.models.User user; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      USER((short)1, "user");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // USER
            return USER;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.USER, new org.apache.thrift.meta_data.FieldMetaData("user", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.User.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createUser_args.class, metaDataMap);
    }

    public createUser_args() {
    }

    public createUser_args(
      org.apache.airavata.sharing.registry.models.User user)
    {
      this();
      this.user = user;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createUser_args(createUser_args other) {
      if (other.isSetUser()) {
        this.user = new org.apache.airavata.sharing.registry.models.User(other.user);
      }
    }

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

    @Override
    public void clear() {
      this.user = null;
    }

    public org.apache.airavata.sharing.registry.models.User getUser() {
      return this.user;
    }

    public createUser_args setUser(org.apache.airavata.sharing.registry.models.User user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

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

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((org.apache.airavata.sharing.registry.models.User)value);
        }
        break;

      }
    }

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

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

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

      switch (field) {
      case USER:
        return isSetUser();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (user == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'user' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (user != null) {
        user.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, java.lang.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 createUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createUser_argsStandardScheme getScheme() {
        return new createUser_argsStandardScheme();
      }
    }

    private static class createUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createUser_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createUser_args 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: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.user = new org.apache.airavata.sharing.registry.models.User();
                struct.user.read(iprot);
                struct.setUserIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          struct.user.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class createUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createUser_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.user.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.user = new org.apache.airavata.sharing.registry.models.User();
        struct.user.read(iprot);
        struct.setUserIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField DEE_FIELD_DESC = new org.apache.thrift.protocol.TField("dee", org.apache.thrift.protocol.TType.STRUCT, (short)2);

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

    public java.lang.String success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required
    public org.apache.airavata.sharing.registry.models.DuplicateEntryException dee; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre"),
      DEE((short)2, "dee");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          case 2: // DEE
            return DEE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      tmpMap.put(_Fields.DEE, new org.apache.thrift.meta_data.FieldMetaData("dee", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.DuplicateEntryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createUser_result.class, metaDataMap);
    }

    public createUser_result() {
    }

    public createUser_result(
      java.lang.String success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre,
      org.apache.airavata.sharing.registry.models.DuplicateEntryException dee)
    {
      this();
      this.success = success;
      this.sre = sre;
      this.dee = dee;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createUser_result(createUser_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
      if (other.isSetDee()) {
        this.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException(other.dee);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
      this.dee = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createUser_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public createUser_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.DuplicateEntryException getDee() {
      return this.dee;
    }

    public createUser_result setDee(org.apache.airavata.sharing.registry.models.DuplicateEntryException dee) {
      this.dee = dee;
      return this;
    }

    public void unsetDee() {
      this.dee = null;
    }

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

    public void setDeeIsSet(boolean value) {
      if (!value) {
        this.dee = null;
      }
    }

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

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      case DEE:
        if (value == null) {
          unsetDee();
        } else {
          setDee((org.apache.airavata.sharing.registry.models.DuplicateEntryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

      case DEE:
        return getDee();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      case DEE:
        return isSetDee();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      boolean this_present_dee = true && this.isSetDee();
      boolean that_present_dee = true && that.isSetDee();
      if (this_present_dee || that_present_dee) {
        if (!(this_present_dee && that_present_dee))
          return false;
        if (!this.dee.equals(that.dee))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      hashCode = hashCode * 8191 + ((isSetDee()) ? 131071 : 524287);
      if (isSetDee())
        hashCode = hashCode * 8191 + dee.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetDee()).compareTo(other.isSetDee());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDee()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dee, other.dee);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("dee:");
      if (this.dee == null) {
        sb.append("null");
      } else {
        sb.append(this.dee);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 createUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createUser_resultStandardScheme getScheme() {
        return new createUser_resultStandardScheme();
      }
    }

    private static class createUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createUser_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createUser_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // DEE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException();
                struct.dee.read(iprot);
                struct.setDeeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.dee != null) {
          oprot.writeFieldBegin(DEE_FIELD_DESC);
          struct.dee.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class createUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createUser_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        if (struct.isSetDee()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
        if (struct.isSetDee()) {
          struct.dee.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException();
          struct.dee.read(iprot);
          struct.setDeeIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField USER_FIELD_DESC = new org.apache.thrift.protocol.TField("user", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.sharing.registry.models.User user; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      USER((short)1, "user");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // USER
            return USER;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.USER, new org.apache.thrift.meta_data.FieldMetaData("user", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.User.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updatedUser_args.class, metaDataMap);
    }

    public updatedUser_args() {
    }

    public updatedUser_args(
      org.apache.airavata.sharing.registry.models.User user)
    {
      this();
      this.user = user;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updatedUser_args(updatedUser_args other) {
      if (other.isSetUser()) {
        this.user = new org.apache.airavata.sharing.registry.models.User(other.user);
      }
    }

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

    @Override
    public void clear() {
      this.user = null;
    }

    public org.apache.airavata.sharing.registry.models.User getUser() {
      return this.user;
    }

    public updatedUser_args setUser(org.apache.airavata.sharing.registry.models.User user) {
      this.user = user;
      return this;
    }

    public void unsetUser() {
      this.user = null;
    }

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

    public void setUserIsSet(boolean value) {
      if (!value) {
        this.user = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case USER:
        if (value == null) {
          unsetUser();
        } else {
          setUser((org.apache.airavata.sharing.registry.models.User)value);
        }
        break;

      }
    }

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

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

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

      switch (field) {
      case USER:
        return isSetUser();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_user = true && this.isSetUser();
      boolean that_present_user = true && that.isSetUser();
      if (this_present_user || that_present_user) {
        if (!(this_present_user && that_present_user))
          return false;
        if (!this.user.equals(that.user))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetUser()) ? 131071 : 524287);
      if (isSetUser())
        hashCode = hashCode * 8191 + user.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetUser()).compareTo(other.isSetUser());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUser()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.user, other.user);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("user:");
      if (this.user == null) {
        sb.append("null");
      } else {
        sb.append(this.user);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (user == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'user' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (user != null) {
        user.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, java.lang.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 updatedUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updatedUser_argsStandardScheme getScheme() {
        return new updatedUser_argsStandardScheme();
      }
    }

    private static class updatedUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updatedUser_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updatedUser_args 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: // USER
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.user = new org.apache.airavata.sharing.registry.models.User();
                struct.user.read(iprot);
                struct.setUserIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updatedUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.user != null) {
          oprot.writeFieldBegin(USER_FIELD_DESC);
          struct.user.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updatedUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updatedUser_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updatedUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.user.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updatedUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.user = new org.apache.airavata.sharing.registry.models.User();
        struct.user.read(iprot);
        struct.setUserIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updatedUser_result.class, metaDataMap);
    }

    public updatedUser_result() {
    }

    public updatedUser_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updatedUser_result(updatedUser_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updatedUser_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public updatedUser_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

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

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

    private static class updatedUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updatedUser_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updatedUser_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updatedUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updatedUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updatedUser_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updatedUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updatedUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("userId", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public java.lang.String domainId; // required
    public java.lang.String userId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      USER_ID((short)2, "userId");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // USER_ID
            return USER_ID;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_ID, new org.apache.thrift.meta_data.FieldMetaData("userId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isUserExists_args.class, metaDataMap);
    }

    public isUserExists_args() {
    }

    public isUserExists_args(
      java.lang.String domainId,
      java.lang.String userId)
    {
      this();
      this.domainId = domainId;
      this.userId = userId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isUserExists_args(isUserExists_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetUserId()) {
        this.userId = other.userId;
      }
    }

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

    @Override
    public void clear() {
      this.domainId = null;
      this.userId = null;
    }

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

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

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

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

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

    public java.lang.String getUserId() {
      return this.userId;
    }

    public isUserExists_args setUserId(java.lang.String userId) {
      this.userId = userId;
      return this;
    }

    public void unsetUserId() {
      this.userId = null;
    }

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

    public void setUserIdIsSet(boolean value) {
      if (!value) {
        this.userId = null;
      }
    }

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

      case USER_ID:
        if (value == null) {
          unsetUserId();
        } else {
          setUserId((java.lang.String)value);
        }
        break;

      }
    }

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

      case USER_ID:
        return getUserId();

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

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

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case USER_ID:
        return isSetUserId();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

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

      boolean this_present_userId = true && this.isSetUserId();
      boolean that_present_userId = true && that.isSetUserId();
      if (this_present_userId || that_present_userId) {
        if (!(this_present_userId && that_present_userId))
          return false;
        if (!this.userId.equals(that.userId))
          return false;
      }

      return true;
    }

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

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

      hashCode = hashCode * 8191 + ((isSetUserId()) ? 131071 : 524287);
      if (isSetUserId())
        hashCode = hashCode * 8191 + userId.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserId()).compareTo(other.isSetUserId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userId, other.userId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userId:");
      if (this.userId == null) {
        sb.append("null");
      } else {
        sb.append(this.userId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (userId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 isUserExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isUserExists_argsStandardScheme getScheme() {
        return new isUserExists_argsStandardScheme();
      }
    }

    private static class isUserExists_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isUserExists_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isUserExists_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userId = iprot.readString();
                struct.setUserIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isUserExists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.userId != null) {
          oprot.writeFieldBegin(USER_ID_FIELD_DESC);
          oprot.writeString(struct.userId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isUserExists_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isUserExists_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isUserExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.userId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isUserExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.userId = iprot.readString();
        struct.setUserIdIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isUserExists_result.class, metaDataMap);
    }

    public isUserExists_result() {
    }

    public isUserExists_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isUserExists_result(isUserExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isUserExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public isUserExists_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

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

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

    private static class isUserExists_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isUserExists_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isUserExists_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isUserExists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class isUserExists_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isUserExists_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isUserExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isUserExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("userId", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public java.lang.String domainId; // required
    public java.lang.String userId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      USER_ID((short)2, "userId");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // USER_ID
            return USER_ID;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_ID, new org.apache.thrift.meta_data.FieldMetaData("userId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteUser_args.class, metaDataMap);
    }

    public deleteUser_args() {
    }

    public deleteUser_args(
      java.lang.String domainId,
      java.lang.String userId)
    {
      this();
      this.domainId = domainId;
      this.userId = userId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteUser_args(deleteUser_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetUserId()) {
        this.userId = other.userId;
      }
    }

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

    @Override
    public void clear() {
      this.domainId = null;
      this.userId = null;
    }

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

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

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

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

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

    public java.lang.String getUserId() {
      return this.userId;
    }

    public deleteUser_args setUserId(java.lang.String userId) {
      this.userId = userId;
      return this;
    }

    public void unsetUserId() {
      this.userId = null;
    }

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

    public void setUserIdIsSet(boolean value) {
      if (!value) {
        this.userId = null;
      }
    }

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

      case USER_ID:
        if (value == null) {
          unsetUserId();
        } else {
          setUserId((java.lang.String)value);
        }
        break;

      }
    }

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

      case USER_ID:
        return getUserId();

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

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

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case USER_ID:
        return isSetUserId();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

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

      boolean this_present_userId = true && this.isSetUserId();
      boolean that_present_userId = true && that.isSetUserId();
      if (this_present_userId || that_present_userId) {
        if (!(this_present_userId && that_present_userId))
          return false;
        if (!this.userId.equals(that.userId))
          return false;
      }

      return true;
    }

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

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

      hashCode = hashCode * 8191 + ((isSetUserId()) ? 131071 : 524287);
      if (isSetUserId())
        hashCode = hashCode * 8191 + userId.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserId()).compareTo(other.isSetUserId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userId, other.userId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userId:");
      if (this.userId == null) {
        sb.append("null");
      } else {
        sb.append(this.userId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (userId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 deleteUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteUser_argsStandardScheme getScheme() {
        return new deleteUser_argsStandardScheme();
      }
    }

    private static class deleteUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteUser_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteUser_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userId = iprot.readString();
                struct.setUserIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.userId != null) {
          oprot.writeFieldBegin(USER_ID_FIELD_DESC);
          oprot.writeString(struct.userId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class deleteUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteUser_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.userId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.userId = iprot.readString();
        struct.setUserIdIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteUser_result.class, metaDataMap);
    }

    public deleteUser_result() {
    }

    public deleteUser_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteUser_result(deleteUser_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteUser_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

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

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

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

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public deleteUser_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

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

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

    private static class deleteUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteUser_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteUser_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class deleteUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteUser_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("userId", org.apache.thrift.protocol.TType.STRING, (short)2);

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

    public java.lang.String domainId; // required
    public java.lang.String userId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      USER_ID((short)2, "userId");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // USER_ID
            return USER_ID;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_ID, new org.apache.thrift.meta_data.FieldMetaData("userId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUser_args.class, metaDataMap);
    }

    public getUser_args() {
    }

    public getUser_args(
      java.lang.String domainId,
      java.lang.String userId)
    {
      this();
      this.domainId = domainId;
      this.userId = userId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUser_args(getUser_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetUserId()) {
        this.userId = other.userId;
      }
    }

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

    @Override
    public void clear() {
      this.domainId = null;
      this.userId = null;
    }

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

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

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

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

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

    public java.lang.String getUserId() {
      return this.userId;
    }

    public getUser_args setUserId(java.lang.String userId) {
      this.userId = userId;
      return this;
    }

    public void unsetUserId() {
      this.userId = null;
    }

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

    public void setUserIdIsSet(boolean value) {
      if (!value) {
        this.userId = null;
      }
    }

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

      case USER_ID:
        if (value == null) {
          unsetUserId();
        } else {
          setUserId((java.lang.String)value);
        }
        break;

      }
    }

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

      case USER_ID:
        return getUserId();

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

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

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case USER_ID:
        return isSetUserId();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

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

      boolean this_present_userId = true && this.isSetUserId();
      boolean that_present_userId = true && that.isSetUserId();
      if (this_present_userId || that_present_userId) {
        if (!(this_present_userId && that_present_userId))
          return false;
        if (!this.userId.equals(that.userId))
          return false;
      }

      return true;
    }

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

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

      hashCode = hashCode * 8191 + ((isSetUserId()) ? 131071 : 524287);
      if (isSetUserId())
        hashCode = hashCode * 8191 + userId.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserId()).compareTo(other.isSetUserId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userId, other.userId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userId:");
      if (this.userId == null) {
        sb.append("null");
      } else {
        sb.append(this.userId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (userId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getUser_argsStandardScheme getScheme() {
        return new getUser_argsStandardScheme();
      }
    }

    private static class getUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getUser_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUser_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userId = iprot.readString();
                struct.setUserIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.userId != null) {
          oprot.writeFieldBegin(USER_ID_FIELD_DESC);
          oprot.writeString(struct.userId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getUser_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.userId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.userId = iprot.readString();
        struct.setUserIdIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.sharing.registry.models.User success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.User.class)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUser_result.class, metaDataMap);
    }

    public getUser_result() {
    }

    public getUser_result(
      org.apache.airavata.sharing.registry.models.User success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUser_result(getUser_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.sharing.registry.models.User(other.success);
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public org.apache.airavata.sharing.registry.models.User getSuccess() {
      return this.success;
    }

    public getUser_result setSuccess(org.apache.airavata.sharing.registry.models.User success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getUser_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.sharing.registry.models.User)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.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, java.lang.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 getUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getUser_resultStandardScheme getScheme() {
        return new getUser_resultStandardScheme();
      }
    }

    private static class getUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getUser_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUser_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.sharing.registry.models.User();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getUser_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.sharing.registry.models.User();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)2);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)3);

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

    public java.lang.String domainId; // required
    public int offset; // required
    public int limit; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      OFFSET((short)2, "offset"),
      LIMIT((short)3, "limit");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // OFFSET
            return OFFSET;
          case 3: // LIMIT
            return LIMIT;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    private static final int __OFFSET_ISSET_ID = 0;
    private static final int __LIMIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUsers_args.class, metaDataMap);
    }

    public getUsers_args() {
    }

    public getUsers_args(
      java.lang.String domainId,
      int offset,
      int limit)
    {
      this();
      this.domainId = domainId;
      this.offset = offset;
      setOffsetIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUsers_args(getUsers_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      this.offset = other.offset;
      this.limit = other.limit;
    }

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

    @Override
    public void clear() {
      this.domainId = null;
      setOffsetIsSet(false);
      this.offset = 0;
      setLimitIsSet(false);
      this.limit = 0;
    }

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

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

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

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

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

    public int getOffset() {
      return this.offset;
    }

    public getUsers_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

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

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

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

    public int getLimit() {
      return this.limit;
    }

    public getUsers_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

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

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

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

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

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((java.lang.Integer)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((java.lang.Integer)value);
        }
        break;

      }
    }

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

      case OFFSET:
        return getOffset();

      case LIMIT:
        return getLimit();

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

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

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case OFFSET:
        return isSetOffset();
      case LIMIT:
        return isSetLimit();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

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

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      return true;
    }

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

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

      hashCode = hashCode * 8191 + offset;

      hashCode = hashCode * 8191 + limit;

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

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

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

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

    private static class getUsers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getUsers_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUsers_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUsers_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getUsers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getUsers_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeI32(struct.offset);
        oprot.writeI32(struct.limit);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public java.util.List<org.apache.airavata.sharing.registry.models.User> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.User.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getUsers_result.class, metaDataMap);
    }

    public getUsers_result() {
    }

    public getUsers_result(
      java.util.List<org.apache.airavata.sharing.registry.models.User> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getUsers_result(getUsers_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.User> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.User other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.User(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

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

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.User> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.User elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> getSuccess() {
      return this.success;
    }

    public getUsers_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.User> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getUsers_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.User>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getUsers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getUsers_resultStandardScheme getScheme() {
        return new getUsers_resultStandardScheme();
      }
    }

    private static class getUsers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getUsers_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getUsers_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list8 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(_list8.size);
                  org.apache.airavata.sharing.registry.models.User _elem9;
                  for (int _i10 = 0; _i10 < _list8.size; ++_i10)
                  {
                    _elem9 = new org.apache.airavata.sharing.registry.models.User();
                    _elem9.read(iprot);
                    struct.success.add(_elem9);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getUsers_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.User _iter11 : struct.success)
            {
              _iter11.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class getUsers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getUsers_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.User _iter12 : struct.success)
            {
              _iter12.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list13 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(_list13.size);
            org.apache.airavata.sharing.registry.models.User _elem14;
            for (int _i15 = 0; _i15 < _list13.size; ++_i15)
            {
              _elem14 = new org.apache.airavata.sharing.registry.models.User();
              _elem14.read(iprot);
              struct.success.add(_elem14);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField GROUP_FIELD_DESC = new org.apache.thrift.protocol.TField("group", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.sharing.registry.models.UserGroup group; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      GROUP((short)1, "group");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // GROUP
            return GROUP;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.GROUP, new org.apache.thrift.meta_data.FieldMetaData("group", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.UserGroup.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createGroup_args.class, metaDataMap);
    }

    public createGroup_args() {
    }

    public createGroup_args(
      org.apache.airavata.sharing.registry.models.UserGroup group)
    {
      this();
      this.group = group;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createGroup_args(createGroup_args other) {
      if (other.isSetGroup()) {
        this.group = new org.apache.airavata.sharing.registry.models.UserGroup(other.group);
      }
    }

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

    @Override
    public void clear() {
      this.group = null;
    }

    public org.apache.airavata.sharing.registry.models.UserGroup getGroup() {
      return this.group;
    }

    public createGroup_args setGroup(org.apache.airavata.sharing.registry.models.UserGroup group) {
      this.group = group;
      return this;
    }

    public void unsetGroup() {
      this.group = null;
    }

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

    public void setGroupIsSet(boolean value) {
      if (!value) {
        this.group = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case GROUP:
        if (value == null) {
          unsetGroup();
        } else {
          setGroup((org.apache.airavata.sharing.registry.models.UserGroup)value);
        }
        break;

      }
    }

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

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

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

      switch (field) {
      case GROUP:
        return isSetGroup();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_group = true && this.isSetGroup();
      boolean that_present_group = true && that.isSetGroup();
      if (this_present_group || that_present_group) {
        if (!(this_present_group && that_present_group))
          return false;
        if (!this.group.equals(that.group))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetGroup()) ? 131071 : 524287);
      if (isSetGroup())
        hashCode = hashCode * 8191 + group.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetGroup()).compareTo(other.isSetGroup());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroup()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.group, other.group);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("group:");
      if (this.group == null) {
        sb.append("null");
      } else {
        sb.append(this.group);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (group == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'group' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (group != null) {
        group.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, java.lang.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 createGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createGroup_argsStandardScheme getScheme() {
        return new createGroup_argsStandardScheme();
      }
    }

    private static class createGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createGroup_args 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: // GROUP
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.group = new org.apache.airavata.sharing.registry.models.UserGroup();
                struct.group.read(iprot);
                struct.setGroupIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.group != null) {
          oprot.writeFieldBegin(GROUP_FIELD_DESC);
          struct.group.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class createGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.group.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.group = new org.apache.airavata.sharing.registry.models.UserGroup();
        struct.group.read(iprot);
        struct.setGroupIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public java.lang.String success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createGroup_result.class, metaDataMap);
    }

    public createGroup_result() {
    }

    public createGroup_result(
      java.lang.String success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createGroup_result(createGroup_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

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

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createGroup_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

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

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public createGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

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

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

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

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

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

      case SRE:
        return getSre();

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

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

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

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

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

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 createGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createGroup_resultStandardScheme getScheme() {
        return new createGroup_resultStandardScheme();
      }
    }

    private static class createGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class createGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField GROUP_FIELD_DESC = new org.apache.thrift.protocol.TField("group", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public org.apache.airavata.sharing.registry.models.UserGroup group; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      GROUP((short)1, "group");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // GROUP
            return GROUP;
          default:
            return null;
        }
      }

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

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

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

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

      public short getThriftFieldId() {
        return _thriftId;
      }

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

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.GROUP, new org.apache.thrift.meta_data.FieldMetaData("group", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.UserGroup.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGroup_args.class, metaDataMap);
    }

    public updateGroup_args() {
    }

    public updateGroup_args(
      org.apache.airavata.sharing.registry.models.UserGroup group)
    {
      this();
      this.group = group;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGroup_args(updateGroup_args other) {
      if (other.isSetGroup()) {
        this.group = new org.apache.airavata.sharing.registry.models.UserGroup(other.group);
      }
    }

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

    @Override
    public void clear() {
      this.group = null;
    }

    public org.apache.airavata.sharing.registry.models.UserGroup getGroup() {
      return this.group;
    }

    public updateGroup_args setGroup(org.apache.airavata.sharing.registry.models.UserGroup group) {
      this.group = group;
      return this;
    }

    public void unsetGroup() {
      this.group = null;
    }

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

    public void setGroupIsSet(boolean value) {
      if (!value) {
        this.group = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case GROUP:
        if (value == null) {
          unsetGroup();
        } else {
          setGroup((org.apache.airavata.sharing.registry.models.UserGroup)value);
        }
        break;

      }
    }

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

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

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

      switch (field) {
      case GROUP:
        return isSetGroup();
      }
      throw new java.lang.IllegalStateException();
    }

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

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

      boolean this_present_group = true && this.isSetGroup();
      boolean that_present_group = true && that.isSetGroup();
      if (this_present_group || that_present_group) {
        if (!(this_present_group && that_present_group))
          return false;
        if (!this.group.equals(that.group))
          return false;
      }

      return true;
    }

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

      hashCode = hashCode * 8191 + ((isSetGroup()) ? 131071 : 524287);
      if (isSetGroup())
        hashCode = hashCode * 8191 + group.hashCode();

      return hashCode;
    }

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

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetGroup()).compareTo(other.isSetGroup());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroup()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.group, other.group);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

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

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

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

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

      sb.append("group:");
      if (this.group == null) {
        sb.append("null");
      } else {
        sb.append(this.group);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (group == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'group' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (group != null) {
        group.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, java.lang.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 updateGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateGroup_argsStandardScheme getScheme() {
        return new updateGroup_argsStandardScheme();
      }
    }

    private static class updateGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGroup_args 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: // GROUP
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.group = new org.apache.airavata.sharing.registry.models.UserGroup();
                struct.group.read(iprot);
                struct.setGroupIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.group != null) {
          oprot.writeFieldBegin(GROUP_FIELD_DESC);
          struct.group.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

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

    private static class updateGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.group.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.group = new org.apache.airavata.sharing.registry.models.UserGroup();
        struct.group.read(iprot);
        struct.setGroupIsSet(true);
      }
    }

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

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

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

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

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

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

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

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

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

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

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateGroup_result.class, metaDataMap);
    }

    public updateGroup_result() {
    }

    public updateGroup_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateGroup_result(updateGroup_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public updateGroup_result deepCopy() {
      return new updateGroup_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateGroup_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public updateGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateGroup_result)
        return this.equals((updateGroup_result)that);
      return false;
    }

    public boolean equals(updateGroup_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateGroup_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateGroup_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateGroup_resultStandardScheme getScheme() {
        return new updateGroup_resultStandardScheme();
      }
    }

    private static class updateGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateGroup_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateGroup_resultTupleScheme getScheme() {
        return new updateGroup_resultTupleScheme();
      }
    }

    private static class updateGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isGroupExists_args implements org.apache.thrift.TBase<isGroupExists_args, isGroupExists_args._Fields>, java.io.Serializable, Cloneable, Comparable<isGroupExists_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isGroupExists_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isGroupExists_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isGroupExists_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isGroupExists_args.class, metaDataMap);
    }

    public isGroupExists_args() {
    }

    public isGroupExists_args(
      java.lang.String domainId,
      java.lang.String groupId)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isGroupExists_args(isGroupExists_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
    }

    public isGroupExists_args deepCopy() {
      return new isGroupExists_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public isGroupExists_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public isGroupExists_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isGroupExists_args)
        return this.equals((isGroupExists_args)that);
      return false;
    }

    public boolean equals(isGroupExists_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isGroupExists_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isGroupExists_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 isGroupExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isGroupExists_argsStandardScheme getScheme() {
        return new isGroupExists_argsStandardScheme();
      }
    }

    private static class isGroupExists_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isGroupExists_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isGroupExists_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isGroupExists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isGroupExists_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isGroupExists_argsTupleScheme getScheme() {
        return new isGroupExists_argsTupleScheme();
      }
    }

    private static class isGroupExists_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isGroupExists_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isGroupExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isGroupExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isGroupExists_result implements org.apache.thrift.TBase<isGroupExists_result, isGroupExists_result._Fields>, java.io.Serializable, Cloneable, Comparable<isGroupExists_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isGroupExists_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isGroupExists_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isGroupExists_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isGroupExists_result.class, metaDataMap);
    }

    public isGroupExists_result() {
    }

    public isGroupExists_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isGroupExists_result(isGroupExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public isGroupExists_result deepCopy() {
      return new isGroupExists_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isGroupExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public isGroupExists_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isGroupExists_result)
        return this.equals((isGroupExists_result)that);
      return false;
    }

    public boolean equals(isGroupExists_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isGroupExists_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isGroupExists_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class isGroupExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isGroupExists_resultStandardScheme getScheme() {
        return new isGroupExists_resultStandardScheme();
      }
    }

    private static class isGroupExists_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isGroupExists_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isGroupExists_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isGroupExists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isGroupExists_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isGroupExists_resultTupleScheme getScheme() {
        return new isGroupExists_resultTupleScheme();
      }
    }

    private static class isGroupExists_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isGroupExists_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isGroupExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isGroupExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deleteGroup_args implements org.apache.thrift.TBase<deleteGroup_args, deleteGroup_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGroup_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGroup_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteGroup_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteGroup_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGroup_args.class, metaDataMap);
    }

    public deleteGroup_args() {
    }

    public deleteGroup_args(
      java.lang.String domainId,
      java.lang.String groupId)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGroup_args(deleteGroup_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
    }

    public deleteGroup_args deepCopy() {
      return new deleteGroup_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public deleteGroup_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public deleteGroup_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGroup_args)
        return this.equals((deleteGroup_args)that);
      return false;
    }

    public boolean equals(deleteGroup_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteGroup_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteGroup_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 deleteGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteGroup_argsStandardScheme getScheme() {
        return new deleteGroup_argsStandardScheme();
      }
    }

    private static class deleteGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGroup_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteGroup_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteGroup_argsTupleScheme getScheme() {
        return new deleteGroup_argsTupleScheme();
      }
    }

    private static class deleteGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deleteGroup_result implements org.apache.thrift.TBase<deleteGroup_result, deleteGroup_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteGroup_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteGroup_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteGroup_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteGroup_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteGroup_result.class, metaDataMap);
    }

    public deleteGroup_result() {
    }

    public deleteGroup_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteGroup_result(deleteGroup_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public deleteGroup_result deepCopy() {
      return new deleteGroup_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteGroup_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public deleteGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteGroup_result)
        return this.equals((deleteGroup_result)that);
      return false;
    }

    public boolean equals(deleteGroup_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteGroup_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteGroup_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteGroup_resultStandardScheme getScheme() {
        return new deleteGroup_resultStandardScheme();
      }
    }

    private static class deleteGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteGroup_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteGroup_resultTupleScheme getScheme() {
        return new deleteGroup_resultTupleScheme();
      }
    }

    private static class deleteGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGroup_args implements org.apache.thrift.TBase<getGroup_args, getGroup_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGroup_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGroup_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGroup_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGroup_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGroup_args.class, metaDataMap);
    }

    public getGroup_args() {
    }

    public getGroup_args(
      java.lang.String domainId,
      java.lang.String groupId)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGroup_args(getGroup_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
    }

    public getGroup_args deepCopy() {
      return new getGroup_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getGroup_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public getGroup_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGroup_args)
        return this.equals((getGroup_args)that);
      return false;
    }

    public boolean equals(getGroup_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getGroup_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGroup_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroup_argsStandardScheme getScheme() {
        return new getGroup_argsStandardScheme();
      }
    }

    private static class getGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGroup_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGroup_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroup_argsTupleScheme getScheme() {
        return new getGroup_argsTupleScheme();
      }
    }

    private static class getGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGroup_result implements org.apache.thrift.TBase<getGroup_result, getGroup_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGroup_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGroup_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGroup_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGroup_resultTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.UserGroup success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.UserGroup.class)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGroup_result.class, metaDataMap);
    }

    public getGroup_result() {
    }

    public getGroup_result(
      org.apache.airavata.sharing.registry.models.UserGroup success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGroup_result(getGroup_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.sharing.registry.models.UserGroup(other.success);
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getGroup_result deepCopy() {
      return new getGroup_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public org.apache.airavata.sharing.registry.models.UserGroup getSuccess() {
      return this.success;
    }

    public getGroup_result setSuccess(org.apache.airavata.sharing.registry.models.UserGroup success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.sharing.registry.models.UserGroup)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGroup_result)
        return this.equals((getGroup_result)that);
      return false;
    }

    public boolean equals(getGroup_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getGroup_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGroup_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.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, java.lang.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 getGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroup_resultStandardScheme getScheme() {
        return new getGroup_resultStandardScheme();
      }
    }

    private static class getGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.sharing.registry.models.UserGroup();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGroup_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroup_resultTupleScheme getScheme() {
        return new getGroup_resultTupleScheme();
      }
    }

    private static class getGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.sharing.registry.models.UserGroup();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGroups_args implements org.apache.thrift.TBase<getGroups_args, getGroups_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGroups_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGroups_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)2);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGroups_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGroups_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public int offset; // required
    public int limit; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      OFFSET((short)2, "offset"),
      LIMIT((short)3, "limit");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // OFFSET
            return OFFSET;
          case 3: // LIMIT
            return LIMIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __OFFSET_ISSET_ID = 0;
    private static final int __LIMIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGroups_args.class, metaDataMap);
    }

    public getGroups_args() {
    }

    public getGroups_args(
      java.lang.String domainId,
      int offset,
      int limit)
    {
      this();
      this.domainId = domainId;
      this.offset = offset;
      setOffsetIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGroups_args(getGroups_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      this.offset = other.offset;
      this.limit = other.limit;
    }

    public getGroups_args deepCopy() {
      return new getGroups_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      setOffsetIsSet(false);
      this.offset = 0;
      setLimitIsSet(false);
      this.limit = 0;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getGroups_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public int getOffset() {
      return this.offset;
    }

    public getGroups_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public int getLimit() {
      return this.limit;
    }

    public getGroups_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((java.lang.Integer)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case OFFSET:
        return getOffset();

      case LIMIT:
        return getLimit();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case OFFSET:
        return isSetOffset();
      case LIMIT:
        return isSetLimit();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGroups_args)
        return this.equals((getGroups_args)that);
      return false;
    }

    public boolean equals(getGroups_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + offset;

      hashCode = hashCode * 8191 + limit;

      return hashCode;
    }

    @Override
    public int compareTo(getGroups_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGroups_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroups_argsStandardScheme getScheme() {
        return new getGroups_argsStandardScheme();
      }
    }

    private static class getGroups_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGroups_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGroups_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGroups_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGroups_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroups_argsTupleScheme getScheme() {
        return new getGroups_argsTupleScheme();
      }
    }

    private static class getGroups_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGroups_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeI32(struct.offset);
        oprot.writeI32(struct.limit);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGroups_result implements org.apache.thrift.TBase<getGroups_result, getGroups_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGroups_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGroups_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGroups_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGroups_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.UserGroup.class))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGroups_result.class, metaDataMap);
    }

    public getGroups_result() {
    }

    public getGroups_result(
      java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success)
    {
      this();
      this.success = success;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGroups_result(getGroups_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.UserGroup other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.UserGroup(other_element));
        }
        this.success = __this__success;
      }
    }

    public getGroups_result deepCopy() {
      return new getGroups_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.UserGroup> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.UserGroup elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getSuccess() {
      return this.success;
    }

    public getGroups_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGroups_result)
        return this.equals((getGroups_result)that);
      return false;
    }

    public boolean equals(getGroups_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getGroups_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGroups_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroups_resultStandardScheme getScheme() {
        return new getGroups_resultStandardScheme();
      }
    }

    private static class getGroups_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGroups_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGroups_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list16 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list16.size);
                  org.apache.airavata.sharing.registry.models.UserGroup _elem17;
                  for (int _i18 = 0; _i18 < _list16.size; ++_i18)
                  {
                    _elem17 = new org.apache.airavata.sharing.registry.models.UserGroup();
                    _elem17.read(iprot);
                    struct.success.add(_elem17);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGroups_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter19 : struct.success)
            {
              _iter19.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroups_resultTupleScheme getScheme() {
        return new getGroups_resultTupleScheme();
      }
    }

    private static class getGroups_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGroups_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter20 : struct.success)
            {
              _iter20.write(oprot);
            }
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list21 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list21.size);
            org.apache.airavata.sharing.registry.models.UserGroup _elem22;
            for (int _i23 = 0; _i23 < _list21.size; ++_i23)
            {
              _elem22 = new org.apache.airavata.sharing.registry.models.UserGroup();
              _elem22.read(iprot);
              struct.success.add(_elem22);
            }
          }
          struct.setSuccessIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class addUsersToGroup_args implements org.apache.thrift.TBase<addUsersToGroup_args, addUsersToGroup_args._Fields>, java.io.Serializable, Cloneable, Comparable<addUsersToGroup_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addUsersToGroup_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_IDS_FIELD_DESC = new org.apache.thrift.protocol.TField("userIds", org.apache.thrift.protocol.TType.LIST, (short)2);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addUsersToGroup_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addUsersToGroup_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.util.List<java.lang.String> userIds; // required
    public java.lang.String groupId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      USER_IDS((short)2, "userIds"),
      GROUP_ID((short)3, "groupId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // USER_IDS
            return USER_IDS;
          case 3: // GROUP_ID
            return GROUP_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_IDS, new org.apache.thrift.meta_data.FieldMetaData("userIds", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addUsersToGroup_args.class, metaDataMap);
    }

    public addUsersToGroup_args() {
    }

    public addUsersToGroup_args(
      java.lang.String domainId,
      java.util.List<java.lang.String> userIds,
      java.lang.String groupId)
    {
      this();
      this.domainId = domainId;
      this.userIds = userIds;
      this.groupId = groupId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addUsersToGroup_args(addUsersToGroup_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetUserIds()) {
        java.util.List<java.lang.String> __this__userIds = new java.util.ArrayList<java.lang.String>(other.userIds);
        this.userIds = __this__userIds;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
    }

    public addUsersToGroup_args deepCopy() {
      return new addUsersToGroup_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.userIds = null;
      this.groupId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public addUsersToGroup_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public int getUserIdsSize() {
      return (this.userIds == null) ? 0 : this.userIds.size();
    }

    public java.util.Iterator<java.lang.String> getUserIdsIterator() {
      return (this.userIds == null) ? null : this.userIds.iterator();
    }

    public void addToUserIds(java.lang.String elem) {
      if (this.userIds == null) {
        this.userIds = new java.util.ArrayList<java.lang.String>();
      }
      this.userIds.add(elem);
    }

    public java.util.List<java.lang.String> getUserIds() {
      return this.userIds;
    }

    public addUsersToGroup_args setUserIds(java.util.List<java.lang.String> userIds) {
      this.userIds = userIds;
      return this;
    }

    public void unsetUserIds() {
      this.userIds = null;
    }

    /** Returns true if field userIds is set (has been assigned a value) and false otherwise */
    public boolean isSetUserIds() {
      return this.userIds != null;
    }

    public void setUserIdsIsSet(boolean value) {
      if (!value) {
        this.userIds = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public addUsersToGroup_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case USER_IDS:
        if (value == null) {
          unsetUserIds();
        } else {
          setUserIds((java.util.List<java.lang.String>)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case USER_IDS:
        return getUserIds();

      case GROUP_ID:
        return getGroupId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case USER_IDS:
        return isSetUserIds();
      case GROUP_ID:
        return isSetGroupId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addUsersToGroup_args)
        return this.equals((addUsersToGroup_args)that);
      return false;
    }

    public boolean equals(addUsersToGroup_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_userIds = true && this.isSetUserIds();
      boolean that_present_userIds = true && that.isSetUserIds();
      if (this_present_userIds || that_present_userIds) {
        if (!(this_present_userIds && that_present_userIds))
          return false;
        if (!this.userIds.equals(that.userIds))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserIds()) ? 131071 : 524287);
      if (isSetUserIds())
        hashCode = hashCode * 8191 + userIds.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addUsersToGroup_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserIds()).compareTo(other.isSetUserIds());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserIds()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userIds, other.userIds);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addUsersToGroup_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userIds:");
      if (this.userIds == null) {
        sb.append("null");
      } else {
        sb.append(this.userIds);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (userIds == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userIds' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 addUsersToGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addUsersToGroup_argsStandardScheme getScheme() {
        return new addUsersToGroup_argsStandardScheme();
      }
    }

    private static class addUsersToGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<addUsersToGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addUsersToGroup_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_IDS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list24 = iprot.readListBegin();
                  struct.userIds = new java.util.ArrayList<java.lang.String>(_list24.size);
                  java.lang.String _elem25;
                  for (int _i26 = 0; _i26 < _list24.size; ++_i26)
                  {
                    _elem25 = iprot.readString();
                    struct.userIds.add(_elem25);
                  }
                  iprot.readListEnd();
                }
                struct.setUserIdsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addUsersToGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.userIds != null) {
          oprot.writeFieldBegin(USER_IDS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.userIds.size()));
            for (java.lang.String _iter27 : struct.userIds)
            {
              oprot.writeString(_iter27);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addUsersToGroup_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addUsersToGroup_argsTupleScheme getScheme() {
        return new addUsersToGroup_argsTupleScheme();
      }
    }

    private static class addUsersToGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<addUsersToGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addUsersToGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        {
          oprot.writeI32(struct.userIds.size());
          for (java.lang.String _iter28 : struct.userIds)
          {
            oprot.writeString(_iter28);
          }
        }
        oprot.writeString(struct.groupId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addUsersToGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list29 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.userIds = new java.util.ArrayList<java.lang.String>(_list29.size);
          java.lang.String _elem30;
          for (int _i31 = 0; _i31 < _list29.size; ++_i31)
          {
            _elem30 = iprot.readString();
            struct.userIds.add(_elem30);
          }
        }
        struct.setUserIdsIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class addUsersToGroup_result implements org.apache.thrift.TBase<addUsersToGroup_result, addUsersToGroup_result._Fields>, java.io.Serializable, Cloneable, Comparable<addUsersToGroup_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addUsersToGroup_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addUsersToGroup_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addUsersToGroup_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addUsersToGroup_result.class, metaDataMap);
    }

    public addUsersToGroup_result() {
    }

    public addUsersToGroup_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addUsersToGroup_result(addUsersToGroup_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public addUsersToGroup_result deepCopy() {
      return new addUsersToGroup_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public addUsersToGroup_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public addUsersToGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addUsersToGroup_result)
        return this.equals((addUsersToGroup_result)that);
      return false;
    }

    public boolean equals(addUsersToGroup_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addUsersToGroup_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addUsersToGroup_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addUsersToGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addUsersToGroup_resultStandardScheme getScheme() {
        return new addUsersToGroup_resultStandardScheme();
      }
    }

    private static class addUsersToGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<addUsersToGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addUsersToGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addUsersToGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addUsersToGroup_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addUsersToGroup_resultTupleScheme getScheme() {
        return new addUsersToGroup_resultTupleScheme();
      }
    }

    private static class addUsersToGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<addUsersToGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addUsersToGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addUsersToGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class removeUsersFromGroup_args implements org.apache.thrift.TBase<removeUsersFromGroup_args, removeUsersFromGroup_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeUsersFromGroup_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeUsersFromGroup_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_IDS_FIELD_DESC = new org.apache.thrift.protocol.TField("userIds", org.apache.thrift.protocol.TType.LIST, (short)2);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeUsersFromGroup_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeUsersFromGroup_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.util.List<java.lang.String> userIds; // required
    public java.lang.String groupId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      USER_IDS((short)2, "userIds"),
      GROUP_ID((short)3, "groupId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // USER_IDS
            return USER_IDS;
          case 3: // GROUP_ID
            return GROUP_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_IDS, new org.apache.thrift.meta_data.FieldMetaData("userIds", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeUsersFromGroup_args.class, metaDataMap);
    }

    public removeUsersFromGroup_args() {
    }

    public removeUsersFromGroup_args(
      java.lang.String domainId,
      java.util.List<java.lang.String> userIds,
      java.lang.String groupId)
    {
      this();
      this.domainId = domainId;
      this.userIds = userIds;
      this.groupId = groupId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeUsersFromGroup_args(removeUsersFromGroup_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetUserIds()) {
        java.util.List<java.lang.String> __this__userIds = new java.util.ArrayList<java.lang.String>(other.userIds);
        this.userIds = __this__userIds;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
    }

    public removeUsersFromGroup_args deepCopy() {
      return new removeUsersFromGroup_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.userIds = null;
      this.groupId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public removeUsersFromGroup_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public int getUserIdsSize() {
      return (this.userIds == null) ? 0 : this.userIds.size();
    }

    public java.util.Iterator<java.lang.String> getUserIdsIterator() {
      return (this.userIds == null) ? null : this.userIds.iterator();
    }

    public void addToUserIds(java.lang.String elem) {
      if (this.userIds == null) {
        this.userIds = new java.util.ArrayList<java.lang.String>();
      }
      this.userIds.add(elem);
    }

    public java.util.List<java.lang.String> getUserIds() {
      return this.userIds;
    }

    public removeUsersFromGroup_args setUserIds(java.util.List<java.lang.String> userIds) {
      this.userIds = userIds;
      return this;
    }

    public void unsetUserIds() {
      this.userIds = null;
    }

    /** Returns true if field userIds is set (has been assigned a value) and false otherwise */
    public boolean isSetUserIds() {
      return this.userIds != null;
    }

    public void setUserIdsIsSet(boolean value) {
      if (!value) {
        this.userIds = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public removeUsersFromGroup_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case USER_IDS:
        if (value == null) {
          unsetUserIds();
        } else {
          setUserIds((java.util.List<java.lang.String>)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case USER_IDS:
        return getUserIds();

      case GROUP_ID:
        return getGroupId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case USER_IDS:
        return isSetUserIds();
      case GROUP_ID:
        return isSetGroupId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeUsersFromGroup_args)
        return this.equals((removeUsersFromGroup_args)that);
      return false;
    }

    public boolean equals(removeUsersFromGroup_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_userIds = true && this.isSetUserIds();
      boolean that_present_userIds = true && that.isSetUserIds();
      if (this_present_userIds || that_present_userIds) {
        if (!(this_present_userIds && that_present_userIds))
          return false;
        if (!this.userIds.equals(that.userIds))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserIds()) ? 131071 : 524287);
      if (isSetUserIds())
        hashCode = hashCode * 8191 + userIds.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeUsersFromGroup_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserIds()).compareTo(other.isSetUserIds());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserIds()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userIds, other.userIds);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeUsersFromGroup_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userIds:");
      if (this.userIds == null) {
        sb.append("null");
      } else {
        sb.append(this.userIds);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (userIds == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userIds' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 removeUsersFromGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeUsersFromGroup_argsStandardScheme getScheme() {
        return new removeUsersFromGroup_argsStandardScheme();
      }
    }

    private static class removeUsersFromGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeUsersFromGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, removeUsersFromGroup_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_IDS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list32 = iprot.readListBegin();
                  struct.userIds = new java.util.ArrayList<java.lang.String>(_list32.size);
                  java.lang.String _elem33;
                  for (int _i34 = 0; _i34 < _list32.size; ++_i34)
                  {
                    _elem33 = iprot.readString();
                    struct.userIds.add(_elem33);
                  }
                  iprot.readListEnd();
                }
                struct.setUserIdsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeUsersFromGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.userIds != null) {
          oprot.writeFieldBegin(USER_IDS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.userIds.size()));
            for (java.lang.String _iter35 : struct.userIds)
            {
              oprot.writeString(_iter35);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeUsersFromGroup_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeUsersFromGroup_argsTupleScheme getScheme() {
        return new removeUsersFromGroup_argsTupleScheme();
      }
    }

    private static class removeUsersFromGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeUsersFromGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, removeUsersFromGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        {
          oprot.writeI32(struct.userIds.size());
          for (java.lang.String _iter36 : struct.userIds)
          {
            oprot.writeString(_iter36);
          }
        }
        oprot.writeString(struct.groupId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeUsersFromGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list37 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.userIds = new java.util.ArrayList<java.lang.String>(_list37.size);
          java.lang.String _elem38;
          for (int _i39 = 0; _i39 < _list37.size; ++_i39)
          {
            _elem38 = iprot.readString();
            struct.userIds.add(_elem38);
          }
        }
        struct.setUserIdsIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class removeUsersFromGroup_result implements org.apache.thrift.TBase<removeUsersFromGroup_result, removeUsersFromGroup_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeUsersFromGroup_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeUsersFromGroup_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeUsersFromGroup_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeUsersFromGroup_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeUsersFromGroup_result.class, metaDataMap);
    }

    public removeUsersFromGroup_result() {
    }

    public removeUsersFromGroup_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeUsersFromGroup_result(removeUsersFromGroup_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public removeUsersFromGroup_result deepCopy() {
      return new removeUsersFromGroup_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public removeUsersFromGroup_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public removeUsersFromGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeUsersFromGroup_result)
        return this.equals((removeUsersFromGroup_result)that);
      return false;
    }

    public boolean equals(removeUsersFromGroup_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeUsersFromGroup_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeUsersFromGroup_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeUsersFromGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeUsersFromGroup_resultStandardScheme getScheme() {
        return new removeUsersFromGroup_resultStandardScheme();
      }
    }

    private static class removeUsersFromGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeUsersFromGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, removeUsersFromGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeUsersFromGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeUsersFromGroup_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeUsersFromGroup_resultTupleScheme getScheme() {
        return new removeUsersFromGroup_resultTupleScheme();
      }
    }

    private static class removeUsersFromGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeUsersFromGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, removeUsersFromGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeUsersFromGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class transferGroupOwnership_args implements org.apache.thrift.TBase<transferGroupOwnership_args, transferGroupOwnership_args._Fields>, java.io.Serializable, Cloneable, Comparable<transferGroupOwnership_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("transferGroupOwnership_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField NEW_OWNER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("newOwnerId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new transferGroupOwnership_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new transferGroupOwnership_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required
    public java.lang.String newOwnerId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId"),
      NEW_OWNER_ID((short)3, "newOwnerId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          case 3: // NEW_OWNER_ID
            return NEW_OWNER_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.NEW_OWNER_ID, new org.apache.thrift.meta_data.FieldMetaData("newOwnerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(transferGroupOwnership_args.class, metaDataMap);
    }

    public transferGroupOwnership_args() {
    }

    public transferGroupOwnership_args(
      java.lang.String domainId,
      java.lang.String groupId,
      java.lang.String newOwnerId)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
      this.newOwnerId = newOwnerId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public transferGroupOwnership_args(transferGroupOwnership_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
      if (other.isSetNewOwnerId()) {
        this.newOwnerId = other.newOwnerId;
      }
    }

    public transferGroupOwnership_args deepCopy() {
      return new transferGroupOwnership_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
      this.newOwnerId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public transferGroupOwnership_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public transferGroupOwnership_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public java.lang.String getNewOwnerId() {
      return this.newOwnerId;
    }

    public transferGroupOwnership_args setNewOwnerId(java.lang.String newOwnerId) {
      this.newOwnerId = newOwnerId;
      return this;
    }

    public void unsetNewOwnerId() {
      this.newOwnerId = null;
    }

    /** Returns true if field newOwnerId is set (has been assigned a value) and false otherwise */
    public boolean isSetNewOwnerId() {
      return this.newOwnerId != null;
    }

    public void setNewOwnerIdIsSet(boolean value) {
      if (!value) {
        this.newOwnerId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      case NEW_OWNER_ID:
        if (value == null) {
          unsetNewOwnerId();
        } else {
          setNewOwnerId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      case NEW_OWNER_ID:
        return getNewOwnerId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      case NEW_OWNER_ID:
        return isSetNewOwnerId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof transferGroupOwnership_args)
        return this.equals((transferGroupOwnership_args)that);
      return false;
    }

    public boolean equals(transferGroupOwnership_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      boolean this_present_newOwnerId = true && this.isSetNewOwnerId();
      boolean that_present_newOwnerId = true && that.isSetNewOwnerId();
      if (this_present_newOwnerId || that_present_newOwnerId) {
        if (!(this_present_newOwnerId && that_present_newOwnerId))
          return false;
        if (!this.newOwnerId.equals(that.newOwnerId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      hashCode = hashCode * 8191 + ((isSetNewOwnerId()) ? 131071 : 524287);
      if (isSetNewOwnerId())
        hashCode = hashCode * 8191 + newOwnerId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(transferGroupOwnership_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetNewOwnerId()).compareTo(other.isSetNewOwnerId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetNewOwnerId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.newOwnerId, other.newOwnerId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("transferGroupOwnership_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("newOwnerId:");
      if (this.newOwnerId == null) {
        sb.append("null");
      } else {
        sb.append(this.newOwnerId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      if (newOwnerId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'newOwnerId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 transferGroupOwnership_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public transferGroupOwnership_argsStandardScheme getScheme() {
        return new transferGroupOwnership_argsStandardScheme();
      }
    }

    private static class transferGroupOwnership_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<transferGroupOwnership_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, transferGroupOwnership_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // NEW_OWNER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.newOwnerId = iprot.readString();
                struct.setNewOwnerIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, transferGroupOwnership_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        if (struct.newOwnerId != null) {
          oprot.writeFieldBegin(NEW_OWNER_ID_FIELD_DESC);
          oprot.writeString(struct.newOwnerId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class transferGroupOwnership_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public transferGroupOwnership_argsTupleScheme getScheme() {
        return new transferGroupOwnership_argsTupleScheme();
      }
    }

    private static class transferGroupOwnership_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<transferGroupOwnership_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, transferGroupOwnership_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
        oprot.writeString(struct.newOwnerId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, transferGroupOwnership_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
        struct.newOwnerId = iprot.readString();
        struct.setNewOwnerIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class transferGroupOwnership_result implements org.apache.thrift.TBase<transferGroupOwnership_result, transferGroupOwnership_result._Fields>, java.io.Serializable, Cloneable, Comparable<transferGroupOwnership_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("transferGroupOwnership_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new transferGroupOwnership_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new transferGroupOwnership_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(transferGroupOwnership_result.class, metaDataMap);
    }

    public transferGroupOwnership_result() {
    }

    public transferGroupOwnership_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public transferGroupOwnership_result(transferGroupOwnership_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public transferGroupOwnership_result deepCopy() {
      return new transferGroupOwnership_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public transferGroupOwnership_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public transferGroupOwnership_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof transferGroupOwnership_result)
        return this.equals((transferGroupOwnership_result)that);
      return false;
    }

    public boolean equals(transferGroupOwnership_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(transferGroupOwnership_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("transferGroupOwnership_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class transferGroupOwnership_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public transferGroupOwnership_resultStandardScheme getScheme() {
        return new transferGroupOwnership_resultStandardScheme();
      }
    }

    private static class transferGroupOwnership_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<transferGroupOwnership_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, transferGroupOwnership_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, transferGroupOwnership_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class transferGroupOwnership_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public transferGroupOwnership_resultTupleScheme getScheme() {
        return new transferGroupOwnership_resultTupleScheme();
      }
    }

    private static class transferGroupOwnership_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<transferGroupOwnership_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, transferGroupOwnership_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, transferGroupOwnership_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class addGroupAdmins_args implements org.apache.thrift.TBase<addGroupAdmins_args, addGroupAdmins_args._Fields>, java.io.Serializable, Cloneable, Comparable<addGroupAdmins_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGroupAdmins_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField ADMIN_IDS_FIELD_DESC = new org.apache.thrift.protocol.TField("adminIds", org.apache.thrift.protocol.TType.LIST, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addGroupAdmins_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addGroupAdmins_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required
    public java.util.List<java.lang.String> adminIds; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId"),
      ADMIN_IDS((short)3, "adminIds");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          case 3: // ADMIN_IDS
            return ADMIN_IDS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ADMIN_IDS, new org.apache.thrift.meta_data.FieldMetaData("adminIds", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGroupAdmins_args.class, metaDataMap);
    }

    public addGroupAdmins_args() {
    }

    public addGroupAdmins_args(
      java.lang.String domainId,
      java.lang.String groupId,
      java.util.List<java.lang.String> adminIds)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
      this.adminIds = adminIds;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGroupAdmins_args(addGroupAdmins_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
      if (other.isSetAdminIds()) {
        java.util.List<java.lang.String> __this__adminIds = new java.util.ArrayList<java.lang.String>(other.adminIds);
        this.adminIds = __this__adminIds;
      }
    }

    public addGroupAdmins_args deepCopy() {
      return new addGroupAdmins_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
      this.adminIds = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public addGroupAdmins_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public addGroupAdmins_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public int getAdminIdsSize() {
      return (this.adminIds == null) ? 0 : this.adminIds.size();
    }

    public java.util.Iterator<java.lang.String> getAdminIdsIterator() {
      return (this.adminIds == null) ? null : this.adminIds.iterator();
    }

    public void addToAdminIds(java.lang.String elem) {
      if (this.adminIds == null) {
        this.adminIds = new java.util.ArrayList<java.lang.String>();
      }
      this.adminIds.add(elem);
    }

    public java.util.List<java.lang.String> getAdminIds() {
      return this.adminIds;
    }

    public addGroupAdmins_args setAdminIds(java.util.List<java.lang.String> adminIds) {
      this.adminIds = adminIds;
      return this;
    }

    public void unsetAdminIds() {
      this.adminIds = null;
    }

    /** Returns true if field adminIds is set (has been assigned a value) and false otherwise */
    public boolean isSetAdminIds() {
      return this.adminIds != null;
    }

    public void setAdminIdsIsSet(boolean value) {
      if (!value) {
        this.adminIds = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      case ADMIN_IDS:
        if (value == null) {
          unsetAdminIds();
        } else {
          setAdminIds((java.util.List<java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      case ADMIN_IDS:
        return getAdminIds();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      case ADMIN_IDS:
        return isSetAdminIds();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addGroupAdmins_args)
        return this.equals((addGroupAdmins_args)that);
      return false;
    }

    public boolean equals(addGroupAdmins_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      boolean this_present_adminIds = true && this.isSetAdminIds();
      boolean that_present_adminIds = true && that.isSetAdminIds();
      if (this_present_adminIds || that_present_adminIds) {
        if (!(this_present_adminIds && that_present_adminIds))
          return false;
        if (!this.adminIds.equals(that.adminIds))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      hashCode = hashCode * 8191 + ((isSetAdminIds()) ? 131071 : 524287);
      if (isSetAdminIds())
        hashCode = hashCode * 8191 + adminIds.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addGroupAdmins_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAdminIds()).compareTo(other.isSetAdminIds());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAdminIds()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.adminIds, other.adminIds);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addGroupAdmins_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("adminIds:");
      if (this.adminIds == null) {
        sb.append("null");
      } else {
        sb.append(this.adminIds);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      if (adminIds == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'adminIds' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 addGroupAdmins_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addGroupAdmins_argsStandardScheme getScheme() {
        return new addGroupAdmins_argsStandardScheme();
      }
    }

    private static class addGroupAdmins_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<addGroupAdmins_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGroupAdmins_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ADMIN_IDS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list40 = iprot.readListBegin();
                  struct.adminIds = new java.util.ArrayList<java.lang.String>(_list40.size);
                  java.lang.String _elem41;
                  for (int _i42 = 0; _i42 < _list40.size; ++_i42)
                  {
                    _elem41 = iprot.readString();
                    struct.adminIds.add(_elem41);
                  }
                  iprot.readListEnd();
                }
                struct.setAdminIdsIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addGroupAdmins_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        if (struct.adminIds != null) {
          oprot.writeFieldBegin(ADMIN_IDS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.adminIds.size()));
            for (java.lang.String _iter43 : struct.adminIds)
            {
              oprot.writeString(_iter43);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addGroupAdmins_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addGroupAdmins_argsTupleScheme getScheme() {
        return new addGroupAdmins_argsTupleScheme();
      }
    }

    private static class addGroupAdmins_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<addGroupAdmins_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGroupAdmins_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
        {
          oprot.writeI32(struct.adminIds.size());
          for (java.lang.String _iter44 : struct.adminIds)
          {
            oprot.writeString(_iter44);
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGroupAdmins_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list45 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.adminIds = new java.util.ArrayList<java.lang.String>(_list45.size);
          java.lang.String _elem46;
          for (int _i47 = 0; _i47 < _list45.size; ++_i47)
          {
            _elem46 = iprot.readString();
            struct.adminIds.add(_elem46);
          }
        }
        struct.setAdminIdsIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class addGroupAdmins_result implements org.apache.thrift.TBase<addGroupAdmins_result, addGroupAdmins_result._Fields>, java.io.Serializable, Cloneable, Comparable<addGroupAdmins_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addGroupAdmins_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addGroupAdmins_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addGroupAdmins_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addGroupAdmins_result.class, metaDataMap);
    }

    public addGroupAdmins_result() {
    }

    public addGroupAdmins_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addGroupAdmins_result(addGroupAdmins_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public addGroupAdmins_result deepCopy() {
      return new addGroupAdmins_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public addGroupAdmins_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public addGroupAdmins_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addGroupAdmins_result)
        return this.equals((addGroupAdmins_result)that);
      return false;
    }

    public boolean equals(addGroupAdmins_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addGroupAdmins_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addGroupAdmins_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addGroupAdmins_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addGroupAdmins_resultStandardScheme getScheme() {
        return new addGroupAdmins_resultStandardScheme();
      }
    }

    private static class addGroupAdmins_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<addGroupAdmins_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addGroupAdmins_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addGroupAdmins_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addGroupAdmins_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addGroupAdmins_resultTupleScheme getScheme() {
        return new addGroupAdmins_resultTupleScheme();
      }
    }

    private static class addGroupAdmins_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<addGroupAdmins_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addGroupAdmins_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addGroupAdmins_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class removeGroupAdmins_args implements org.apache.thrift.TBase<removeGroupAdmins_args, removeGroupAdmins_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeGroupAdmins_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeGroupAdmins_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField ADMIN_IDS_FIELD_DESC = new org.apache.thrift.protocol.TField("adminIds", org.apache.thrift.protocol.TType.LIST, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeGroupAdmins_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeGroupAdmins_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required
    public java.util.List<java.lang.String> adminIds; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId"),
      ADMIN_IDS((short)3, "adminIds");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          case 3: // ADMIN_IDS
            return ADMIN_IDS;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ADMIN_IDS, new org.apache.thrift.meta_data.FieldMetaData("adminIds", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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))));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeGroupAdmins_args.class, metaDataMap);
    }

    public removeGroupAdmins_args() {
    }

    public removeGroupAdmins_args(
      java.lang.String domainId,
      java.lang.String groupId,
      java.util.List<java.lang.String> adminIds)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
      this.adminIds = adminIds;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeGroupAdmins_args(removeGroupAdmins_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
      if (other.isSetAdminIds()) {
        java.util.List<java.lang.String> __this__adminIds = new java.util.ArrayList<java.lang.String>(other.adminIds);
        this.adminIds = __this__adminIds;
      }
    }

    public removeGroupAdmins_args deepCopy() {
      return new removeGroupAdmins_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
      this.adminIds = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public removeGroupAdmins_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public removeGroupAdmins_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public int getAdminIdsSize() {
      return (this.adminIds == null) ? 0 : this.adminIds.size();
    }

    public java.util.Iterator<java.lang.String> getAdminIdsIterator() {
      return (this.adminIds == null) ? null : this.adminIds.iterator();
    }

    public void addToAdminIds(java.lang.String elem) {
      if (this.adminIds == null) {
        this.adminIds = new java.util.ArrayList<java.lang.String>();
      }
      this.adminIds.add(elem);
    }

    public java.util.List<java.lang.String> getAdminIds() {
      return this.adminIds;
    }

    public removeGroupAdmins_args setAdminIds(java.util.List<java.lang.String> adminIds) {
      this.adminIds = adminIds;
      return this;
    }

    public void unsetAdminIds() {
      this.adminIds = null;
    }

    /** Returns true if field adminIds is set (has been assigned a value) and false otherwise */
    public boolean isSetAdminIds() {
      return this.adminIds != null;
    }

    public void setAdminIdsIsSet(boolean value) {
      if (!value) {
        this.adminIds = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      case ADMIN_IDS:
        if (value == null) {
          unsetAdminIds();
        } else {
          setAdminIds((java.util.List<java.lang.String>)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      case ADMIN_IDS:
        return getAdminIds();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      case ADMIN_IDS:
        return isSetAdminIds();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeGroupAdmins_args)
        return this.equals((removeGroupAdmins_args)that);
      return false;
    }

    public boolean equals(removeGroupAdmins_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      boolean this_present_adminIds = true && this.isSetAdminIds();
      boolean that_present_adminIds = true && that.isSetAdminIds();
      if (this_present_adminIds || that_present_adminIds) {
        if (!(this_present_adminIds && that_present_adminIds))
          return false;
        if (!this.adminIds.equals(that.adminIds))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      hashCode = hashCode * 8191 + ((isSetAdminIds()) ? 131071 : 524287);
      if (isSetAdminIds())
        hashCode = hashCode * 8191 + adminIds.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeGroupAdmins_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAdminIds()).compareTo(other.isSetAdminIds());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAdminIds()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.adminIds, other.adminIds);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeGroupAdmins_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("adminIds:");
      if (this.adminIds == null) {
        sb.append("null");
      } else {
        sb.append(this.adminIds);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      if (adminIds == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'adminIds' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 removeGroupAdmins_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeGroupAdmins_argsStandardScheme getScheme() {
        return new removeGroupAdmins_argsStandardScheme();
      }
    }

    private static class removeGroupAdmins_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeGroupAdmins_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, removeGroupAdmins_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ADMIN_IDS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list48 = iprot.readListBegin();
                  struct.adminIds = new java.util.ArrayList<java.lang.String>(_list48.size);
                  java.lang.String _elem49;
                  for (int _i50 = 0; _i50 < _list48.size; ++_i50)
                  {
                    _elem49 = iprot.readString();
                    struct.adminIds.add(_elem49);
                  }
                  iprot.readListEnd();
                }
                struct.setAdminIdsIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeGroupAdmins_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        if (struct.adminIds != null) {
          oprot.writeFieldBegin(ADMIN_IDS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.adminIds.size()));
            for (java.lang.String _iter51 : struct.adminIds)
            {
              oprot.writeString(_iter51);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeGroupAdmins_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeGroupAdmins_argsTupleScheme getScheme() {
        return new removeGroupAdmins_argsTupleScheme();
      }
    }

    private static class removeGroupAdmins_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeGroupAdmins_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, removeGroupAdmins_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
        {
          oprot.writeI32(struct.adminIds.size());
          for (java.lang.String _iter52 : struct.adminIds)
          {
            oprot.writeString(_iter52);
          }
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeGroupAdmins_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list53 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.adminIds = new java.util.ArrayList<java.lang.String>(_list53.size);
          java.lang.String _elem54;
          for (int _i55 = 0; _i55 < _list53.size; ++_i55)
          {
            _elem54 = iprot.readString();
            struct.adminIds.add(_elem54);
          }
        }
        struct.setAdminIdsIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class removeGroupAdmins_result implements org.apache.thrift.TBase<removeGroupAdmins_result, removeGroupAdmins_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeGroupAdmins_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeGroupAdmins_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeGroupAdmins_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeGroupAdmins_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeGroupAdmins_result.class, metaDataMap);
    }

    public removeGroupAdmins_result() {
    }

    public removeGroupAdmins_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeGroupAdmins_result(removeGroupAdmins_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public removeGroupAdmins_result deepCopy() {
      return new removeGroupAdmins_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public removeGroupAdmins_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public removeGroupAdmins_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeGroupAdmins_result)
        return this.equals((removeGroupAdmins_result)that);
      return false;
    }

    public boolean equals(removeGroupAdmins_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeGroupAdmins_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeGroupAdmins_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeGroupAdmins_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeGroupAdmins_resultStandardScheme getScheme() {
        return new removeGroupAdmins_resultStandardScheme();
      }
    }

    private static class removeGroupAdmins_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeGroupAdmins_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, removeGroupAdmins_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeGroupAdmins_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeGroupAdmins_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeGroupAdmins_resultTupleScheme getScheme() {
        return new removeGroupAdmins_resultTupleScheme();
      }
    }

    private static class removeGroupAdmins_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeGroupAdmins_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, removeGroupAdmins_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeGroupAdmins_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class hasAdminAccess_args implements org.apache.thrift.TBase<hasAdminAccess_args, hasAdminAccess_args._Fields>, java.io.Serializable, Cloneable, Comparable<hasAdminAccess_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasAdminAccess_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField ADMIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("adminId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasAdminAccess_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasAdminAccess_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required
    public java.lang.String adminId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId"),
      ADMIN_ID((short)3, "adminId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          case 3: // ADMIN_ID
            return ADMIN_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ADMIN_ID, new org.apache.thrift.meta_data.FieldMetaData("adminId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasAdminAccess_args.class, metaDataMap);
    }

    public hasAdminAccess_args() {
    }

    public hasAdminAccess_args(
      java.lang.String domainId,
      java.lang.String groupId,
      java.lang.String adminId)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
      this.adminId = adminId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasAdminAccess_args(hasAdminAccess_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
      if (other.isSetAdminId()) {
        this.adminId = other.adminId;
      }
    }

    public hasAdminAccess_args deepCopy() {
      return new hasAdminAccess_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
      this.adminId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public hasAdminAccess_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public hasAdminAccess_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public java.lang.String getAdminId() {
      return this.adminId;
    }

    public hasAdminAccess_args setAdminId(java.lang.String adminId) {
      this.adminId = adminId;
      return this;
    }

    public void unsetAdminId() {
      this.adminId = null;
    }

    /** Returns true if field adminId is set (has been assigned a value) and false otherwise */
    public boolean isSetAdminId() {
      return this.adminId != null;
    }

    public void setAdminIdIsSet(boolean value) {
      if (!value) {
        this.adminId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      case ADMIN_ID:
        if (value == null) {
          unsetAdminId();
        } else {
          setAdminId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      case ADMIN_ID:
        return getAdminId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      case ADMIN_ID:
        return isSetAdminId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasAdminAccess_args)
        return this.equals((hasAdminAccess_args)that);
      return false;
    }

    public boolean equals(hasAdminAccess_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      boolean this_present_adminId = true && this.isSetAdminId();
      boolean that_present_adminId = true && that.isSetAdminId();
      if (this_present_adminId || that_present_adminId) {
        if (!(this_present_adminId && that_present_adminId))
          return false;
        if (!this.adminId.equals(that.adminId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      hashCode = hashCode * 8191 + ((isSetAdminId()) ? 131071 : 524287);
      if (isSetAdminId())
        hashCode = hashCode * 8191 + adminId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasAdminAccess_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetAdminId()).compareTo(other.isSetAdminId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetAdminId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.adminId, other.adminId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasAdminAccess_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("adminId:");
      if (this.adminId == null) {
        sb.append("null");
      } else {
        sb.append(this.adminId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      if (adminId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'adminId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 hasAdminAccess_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasAdminAccess_argsStandardScheme getScheme() {
        return new hasAdminAccess_argsStandardScheme();
      }
    }

    private static class hasAdminAccess_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasAdminAccess_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, hasAdminAccess_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ADMIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.adminId = iprot.readString();
                struct.setAdminIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasAdminAccess_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        if (struct.adminId != null) {
          oprot.writeFieldBegin(ADMIN_ID_FIELD_DESC);
          oprot.writeString(struct.adminId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasAdminAccess_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasAdminAccess_argsTupleScheme getScheme() {
        return new hasAdminAccess_argsTupleScheme();
      }
    }

    private static class hasAdminAccess_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasAdminAccess_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, hasAdminAccess_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
        oprot.writeString(struct.adminId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasAdminAccess_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
        struct.adminId = iprot.readString();
        struct.setAdminIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class hasAdminAccess_result implements org.apache.thrift.TBase<hasAdminAccess_result, hasAdminAccess_result._Fields>, java.io.Serializable, Cloneable, Comparable<hasAdminAccess_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasAdminAccess_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasAdminAccess_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasAdminAccess_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasAdminAccess_result.class, metaDataMap);
    }

    public hasAdminAccess_result() {
    }

    public hasAdminAccess_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasAdminAccess_result(hasAdminAccess_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public hasAdminAccess_result deepCopy() {
      return new hasAdminAccess_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public hasAdminAccess_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public hasAdminAccess_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasAdminAccess_result)
        return this.equals((hasAdminAccess_result)that);
      return false;
    }

    public boolean equals(hasAdminAccess_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasAdminAccess_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasAdminAccess_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasAdminAccess_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasAdminAccess_resultStandardScheme getScheme() {
        return new hasAdminAccess_resultStandardScheme();
      }
    }

    private static class hasAdminAccess_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasAdminAccess_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, hasAdminAccess_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasAdminAccess_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasAdminAccess_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasAdminAccess_resultTupleScheme getScheme() {
        return new hasAdminAccess_resultTupleScheme();
      }
    }

    private static class hasAdminAccess_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasAdminAccess_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, hasAdminAccess_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasAdminAccess_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class hasOwnerAccess_args implements org.apache.thrift.TBase<hasOwnerAccess_args, hasOwnerAccess_args._Fields>, java.io.Serializable, Cloneable, Comparable<hasOwnerAccess_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasOwnerAccess_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField OWNER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("ownerId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasOwnerAccess_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasOwnerAccess_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required
    public java.lang.String ownerId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId"),
      OWNER_ID((short)3, "ownerId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          case 3: // OWNER_ID
            return OWNER_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.OWNER_ID, new org.apache.thrift.meta_data.FieldMetaData("ownerId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasOwnerAccess_args.class, metaDataMap);
    }

    public hasOwnerAccess_args() {
    }

    public hasOwnerAccess_args(
      java.lang.String domainId,
      java.lang.String groupId,
      java.lang.String ownerId)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
      this.ownerId = ownerId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasOwnerAccess_args(hasOwnerAccess_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
      if (other.isSetOwnerId()) {
        this.ownerId = other.ownerId;
      }
    }

    public hasOwnerAccess_args deepCopy() {
      return new hasOwnerAccess_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
      this.ownerId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public hasOwnerAccess_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public hasOwnerAccess_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public java.lang.String getOwnerId() {
      return this.ownerId;
    }

    public hasOwnerAccess_args setOwnerId(java.lang.String ownerId) {
      this.ownerId = ownerId;
      return this;
    }

    public void unsetOwnerId() {
      this.ownerId = null;
    }

    /** Returns true if field ownerId is set (has been assigned a value) and false otherwise */
    public boolean isSetOwnerId() {
      return this.ownerId != null;
    }

    public void setOwnerIdIsSet(boolean value) {
      if (!value) {
        this.ownerId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      case OWNER_ID:
        if (value == null) {
          unsetOwnerId();
        } else {
          setOwnerId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      case OWNER_ID:
        return getOwnerId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      case OWNER_ID:
        return isSetOwnerId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasOwnerAccess_args)
        return this.equals((hasOwnerAccess_args)that);
      return false;
    }

    public boolean equals(hasOwnerAccess_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      boolean this_present_ownerId = true && this.isSetOwnerId();
      boolean that_present_ownerId = true && that.isSetOwnerId();
      if (this_present_ownerId || that_present_ownerId) {
        if (!(this_present_ownerId && that_present_ownerId))
          return false;
        if (!this.ownerId.equals(that.ownerId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      hashCode = hashCode * 8191 + ((isSetOwnerId()) ? 131071 : 524287);
      if (isSetOwnerId())
        hashCode = hashCode * 8191 + ownerId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasOwnerAccess_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOwnerId()).compareTo(other.isSetOwnerId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOwnerId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ownerId, other.ownerId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasOwnerAccess_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("ownerId:");
      if (this.ownerId == null) {
        sb.append("null");
      } else {
        sb.append(this.ownerId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      if (ownerId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'ownerId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 hasOwnerAccess_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasOwnerAccess_argsStandardScheme getScheme() {
        return new hasOwnerAccess_argsStandardScheme();
      }
    }

    private static class hasOwnerAccess_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasOwnerAccess_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, hasOwnerAccess_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OWNER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.ownerId = iprot.readString();
                struct.setOwnerIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasOwnerAccess_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        if (struct.ownerId != null) {
          oprot.writeFieldBegin(OWNER_ID_FIELD_DESC);
          oprot.writeString(struct.ownerId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasOwnerAccess_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasOwnerAccess_argsTupleScheme getScheme() {
        return new hasOwnerAccess_argsTupleScheme();
      }
    }

    private static class hasOwnerAccess_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasOwnerAccess_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, hasOwnerAccess_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
        oprot.writeString(struct.ownerId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasOwnerAccess_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
        struct.ownerId = iprot.readString();
        struct.setOwnerIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class hasOwnerAccess_result implements org.apache.thrift.TBase<hasOwnerAccess_result, hasOwnerAccess_result._Fields>, java.io.Serializable, Cloneable, Comparable<hasOwnerAccess_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("hasOwnerAccess_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new hasOwnerAccess_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new hasOwnerAccess_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(hasOwnerAccess_result.class, metaDataMap);
    }

    public hasOwnerAccess_result() {
    }

    public hasOwnerAccess_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public hasOwnerAccess_result(hasOwnerAccess_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public hasOwnerAccess_result deepCopy() {
      return new hasOwnerAccess_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public hasOwnerAccess_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public hasOwnerAccess_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof hasOwnerAccess_result)
        return this.equals((hasOwnerAccess_result)that);
      return false;
    }

    public boolean equals(hasOwnerAccess_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(hasOwnerAccess_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("hasOwnerAccess_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class hasOwnerAccess_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasOwnerAccess_resultStandardScheme getScheme() {
        return new hasOwnerAccess_resultStandardScheme();
      }
    }

    private static class hasOwnerAccess_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<hasOwnerAccess_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, hasOwnerAccess_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, hasOwnerAccess_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class hasOwnerAccess_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public hasOwnerAccess_resultTupleScheme getScheme() {
        return new hasOwnerAccess_resultTupleScheme();
      }
    }

    private static class hasOwnerAccess_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<hasOwnerAccess_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, hasOwnerAccess_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, hasOwnerAccess_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGroupMembersOfTypeUser_args implements org.apache.thrift.TBase<getGroupMembersOfTypeUser_args, getGroupMembersOfTypeUser_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGroupMembersOfTypeUser_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGroupMembersOfTypeUser_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGroupMembersOfTypeUser_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGroupMembersOfTypeUser_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required
    public int offset; // required
    public int limit; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId"),
      OFFSET((short)3, "offset"),
      LIMIT((short)4, "limit");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          case 3: // OFFSET
            return OFFSET;
          case 4: // LIMIT
            return LIMIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __OFFSET_ISSET_ID = 0;
    private static final int __LIMIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGroupMembersOfTypeUser_args.class, metaDataMap);
    }

    public getGroupMembersOfTypeUser_args() {
    }

    public getGroupMembersOfTypeUser_args(
      java.lang.String domainId,
      java.lang.String groupId,
      int offset,
      int limit)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
      this.offset = offset;
      setOffsetIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGroupMembersOfTypeUser_args(getGroupMembersOfTypeUser_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
      this.offset = other.offset;
      this.limit = other.limit;
    }

    public getGroupMembersOfTypeUser_args deepCopy() {
      return new getGroupMembersOfTypeUser_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
      setOffsetIsSet(false);
      this.offset = 0;
      setLimitIsSet(false);
      this.limit = 0;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getGroupMembersOfTypeUser_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public getGroupMembersOfTypeUser_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public int getOffset() {
      return this.offset;
    }

    public getGroupMembersOfTypeUser_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public int getLimit() {
      return this.limit;
    }

    public getGroupMembersOfTypeUser_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((java.lang.Integer)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      case OFFSET:
        return getOffset();

      case LIMIT:
        return getLimit();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      case OFFSET:
        return isSetOffset();
      case LIMIT:
        return isSetLimit();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGroupMembersOfTypeUser_args)
        return this.equals((getGroupMembersOfTypeUser_args)that);
      return false;
    }

    public boolean equals(getGroupMembersOfTypeUser_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      hashCode = hashCode * 8191 + offset;

      hashCode = hashCode * 8191 + limit;

      return hashCode;
    }

    @Override
    public int compareTo(getGroupMembersOfTypeUser_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGroupMembersOfTypeUser_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getGroupMembersOfTypeUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroupMembersOfTypeUser_argsStandardScheme getScheme() {
        return new getGroupMembersOfTypeUser_argsStandardScheme();
      }
    }

    private static class getGroupMembersOfTypeUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGroupMembersOfTypeUser_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGroupMembersOfTypeUser_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGroupMembersOfTypeUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGroupMembersOfTypeUser_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroupMembersOfTypeUser_argsTupleScheme getScheme() {
        return new getGroupMembersOfTypeUser_argsTupleScheme();
      }
    }

    private static class getGroupMembersOfTypeUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGroupMembersOfTypeUser_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGroupMembersOfTypeUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.groupId);
        oprot.writeI32(struct.offset);
        oprot.writeI32(struct.limit);
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetDomainId()) {
          optionals.set(0);
        }
        oprot.writeBitSet(optionals, 1);
        if (struct.isSetDomainId()) {
          oprot.writeString(struct.domainId);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGroupMembersOfTypeUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
        java.util.BitSet incoming = iprot.readBitSet(1);
        if (incoming.get(0)) {
          struct.domainId = iprot.readString();
          struct.setDomainIdIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGroupMembersOfTypeUser_result implements org.apache.thrift.TBase<getGroupMembersOfTypeUser_result, getGroupMembersOfTypeUser_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGroupMembersOfTypeUser_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGroupMembersOfTypeUser_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGroupMembersOfTypeUser_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGroupMembersOfTypeUser_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.User> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.User.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGroupMembersOfTypeUser_result.class, metaDataMap);
    }

    public getGroupMembersOfTypeUser_result() {
    }

    public getGroupMembersOfTypeUser_result(
      java.util.List<org.apache.airavata.sharing.registry.models.User> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGroupMembersOfTypeUser_result(getGroupMembersOfTypeUser_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.User> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.User other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.User(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getGroupMembersOfTypeUser_result deepCopy() {
      return new getGroupMembersOfTypeUser_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.User> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.User elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> getSuccess() {
      return this.success;
    }

    public getGroupMembersOfTypeUser_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.User> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getGroupMembersOfTypeUser_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.User>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGroupMembersOfTypeUser_result)
        return this.equals((getGroupMembersOfTypeUser_result)that);
      return false;
    }

    public boolean equals(getGroupMembersOfTypeUser_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getGroupMembersOfTypeUser_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGroupMembersOfTypeUser_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getGroupMembersOfTypeUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroupMembersOfTypeUser_resultStandardScheme getScheme() {
        return new getGroupMembersOfTypeUser_resultStandardScheme();
      }
    }

    private static class getGroupMembersOfTypeUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGroupMembersOfTypeUser_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGroupMembersOfTypeUser_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list56 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(_list56.size);
                  org.apache.airavata.sharing.registry.models.User _elem57;
                  for (int _i58 = 0; _i58 < _list56.size; ++_i58)
                  {
                    _elem57 = new org.apache.airavata.sharing.registry.models.User();
                    _elem57.read(iprot);
                    struct.success.add(_elem57);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGroupMembersOfTypeUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.User _iter59 : struct.success)
            {
              _iter59.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGroupMembersOfTypeUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroupMembersOfTypeUser_resultTupleScheme getScheme() {
        return new getGroupMembersOfTypeUser_resultTupleScheme();
      }
    }

    private static class getGroupMembersOfTypeUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGroupMembersOfTypeUser_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGroupMembersOfTypeUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.User _iter60 : struct.success)
            {
              _iter60.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGroupMembersOfTypeUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list61 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(_list61.size);
            org.apache.airavata.sharing.registry.models.User _elem62;
            for (int _i63 = 0; _i63 < _list61.size; ++_i63)
            {
              _elem62 = new org.apache.airavata.sharing.registry.models.User();
              _elem62.read(iprot);
              struct.success.add(_elem62);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGroupMembersOfTypeGroup_args implements org.apache.thrift.TBase<getGroupMembersOfTypeGroup_args, getGroupMembersOfTypeGroup_args._Fields>, java.io.Serializable, Cloneable, Comparable<getGroupMembersOfTypeGroup_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGroupMembersOfTypeGroup_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)3);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)4);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGroupMembersOfTypeGroup_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGroupMembersOfTypeGroup_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String groupId; // required
    public int offset; // required
    public int limit; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      GROUP_ID((short)2, "groupId"),
      OFFSET((short)3, "offset"),
      LIMIT((short)4, "limit");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // GROUP_ID
            return GROUP_ID;
          case 3: // OFFSET
            return OFFSET;
          case 4: // LIMIT
            return LIMIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __OFFSET_ISSET_ID = 0;
    private static final int __LIMIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGroupMembersOfTypeGroup_args.class, metaDataMap);
    }

    public getGroupMembersOfTypeGroup_args() {
    }

    public getGroupMembersOfTypeGroup_args(
      java.lang.String domainId,
      java.lang.String groupId,
      int offset,
      int limit)
    {
      this();
      this.domainId = domainId;
      this.groupId = groupId;
      this.offset = offset;
      setOffsetIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGroupMembersOfTypeGroup_args(getGroupMembersOfTypeGroup_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
      this.offset = other.offset;
      this.limit = other.limit;
    }

    public getGroupMembersOfTypeGroup_args deepCopy() {
      return new getGroupMembersOfTypeGroup_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.groupId = null;
      setOffsetIsSet(false);
      this.offset = 0;
      setLimitIsSet(false);
      this.limit = 0;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getGroupMembersOfTypeGroup_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public getGroupMembersOfTypeGroup_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public int getOffset() {
      return this.offset;
    }

    public getGroupMembersOfTypeGroup_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public int getLimit() {
      return this.limit;
    }

    public getGroupMembersOfTypeGroup_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((java.lang.Integer)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case GROUP_ID:
        return getGroupId();

      case OFFSET:
        return getOffset();

      case LIMIT:
        return getLimit();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case GROUP_ID:
        return isSetGroupId();
      case OFFSET:
        return isSetOffset();
      case LIMIT:
        return isSetLimit();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGroupMembersOfTypeGroup_args)
        return this.equals((getGroupMembersOfTypeGroup_args)that);
      return false;
    }

    public boolean equals(getGroupMembersOfTypeGroup_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      hashCode = hashCode * 8191 + offset;

      hashCode = hashCode * 8191 + limit;

      return hashCode;
    }

    @Override
    public int compareTo(getGroupMembersOfTypeGroup_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGroupMembersOfTypeGroup_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getGroupMembersOfTypeGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroupMembersOfTypeGroup_argsStandardScheme getScheme() {
        return new getGroupMembersOfTypeGroup_argsStandardScheme();
      }
    }

    private static class getGroupMembersOfTypeGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGroupMembersOfTypeGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGroupMembersOfTypeGroup_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGroupMembersOfTypeGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGroupMembersOfTypeGroup_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroupMembersOfTypeGroup_argsTupleScheme getScheme() {
        return new getGroupMembersOfTypeGroup_argsTupleScheme();
      }
    }

    private static class getGroupMembersOfTypeGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGroupMembersOfTypeGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGroupMembersOfTypeGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.groupId);
        oprot.writeI32(struct.offset);
        oprot.writeI32(struct.limit);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGroupMembersOfTypeGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getGroupMembersOfTypeGroup_result implements org.apache.thrift.TBase<getGroupMembersOfTypeGroup_result, getGroupMembersOfTypeGroup_result._Fields>, java.io.Serializable, Cloneable, Comparable<getGroupMembersOfTypeGroup_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getGroupMembersOfTypeGroup_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getGroupMembersOfTypeGroup_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getGroupMembersOfTypeGroup_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.UserGroup.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getGroupMembersOfTypeGroup_result.class, metaDataMap);
    }

    public getGroupMembersOfTypeGroup_result() {
    }

    public getGroupMembersOfTypeGroup_result(
      java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getGroupMembersOfTypeGroup_result(getGroupMembersOfTypeGroup_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.UserGroup other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.UserGroup(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getGroupMembersOfTypeGroup_result deepCopy() {
      return new getGroupMembersOfTypeGroup_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.UserGroup> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.UserGroup elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getSuccess() {
      return this.success;
    }

    public getGroupMembersOfTypeGroup_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getGroupMembersOfTypeGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getGroupMembersOfTypeGroup_result)
        return this.equals((getGroupMembersOfTypeGroup_result)that);
      return false;
    }

    public boolean equals(getGroupMembersOfTypeGroup_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getGroupMembersOfTypeGroup_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getGroupMembersOfTypeGroup_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getGroupMembersOfTypeGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroupMembersOfTypeGroup_resultStandardScheme getScheme() {
        return new getGroupMembersOfTypeGroup_resultStandardScheme();
      }
    }

    private static class getGroupMembersOfTypeGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getGroupMembersOfTypeGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getGroupMembersOfTypeGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list64 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list64.size);
                  org.apache.airavata.sharing.registry.models.UserGroup _elem65;
                  for (int _i66 = 0; _i66 < _list64.size; ++_i66)
                  {
                    _elem65 = new org.apache.airavata.sharing.registry.models.UserGroup();
                    _elem65.read(iprot);
                    struct.success.add(_elem65);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getGroupMembersOfTypeGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter67 : struct.success)
            {
              _iter67.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getGroupMembersOfTypeGroup_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getGroupMembersOfTypeGroup_resultTupleScheme getScheme() {
        return new getGroupMembersOfTypeGroup_resultTupleScheme();
      }
    }

    private static class getGroupMembersOfTypeGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getGroupMembersOfTypeGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getGroupMembersOfTypeGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter68 : struct.success)
            {
              _iter68.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getGroupMembersOfTypeGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list69 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list69.size);
            org.apache.airavata.sharing.registry.models.UserGroup _elem70;
            for (int _i71 = 0; _i71 < _list69.size; ++_i71)
            {
              _elem70 = new org.apache.airavata.sharing.registry.models.UserGroup();
              _elem70.read(iprot);
              struct.success.add(_elem70);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class addChildGroupsToParentGroup_args implements org.apache.thrift.TBase<addChildGroupsToParentGroup_args, addChildGroupsToParentGroup_args._Fields>, java.io.Serializable, Cloneable, Comparable<addChildGroupsToParentGroup_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addChildGroupsToParentGroup_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField CHILD_IDS_FIELD_DESC = new org.apache.thrift.protocol.TField("childIds", org.apache.thrift.protocol.TType.LIST, (short)2);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addChildGroupsToParentGroup_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addChildGroupsToParentGroup_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.util.List<java.lang.String> childIds; // required
    public java.lang.String groupId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      CHILD_IDS((short)2, "childIds"),
      GROUP_ID((short)3, "groupId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // CHILD_IDS
            return CHILD_IDS;
          case 3: // GROUP_ID
            return GROUP_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.CHILD_IDS, new org.apache.thrift.meta_data.FieldMetaData("childIds", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addChildGroupsToParentGroup_args.class, metaDataMap);
    }

    public addChildGroupsToParentGroup_args() {
    }

    public addChildGroupsToParentGroup_args(
      java.lang.String domainId,
      java.util.List<java.lang.String> childIds,
      java.lang.String groupId)
    {
      this();
      this.domainId = domainId;
      this.childIds = childIds;
      this.groupId = groupId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addChildGroupsToParentGroup_args(addChildGroupsToParentGroup_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetChildIds()) {
        java.util.List<java.lang.String> __this__childIds = new java.util.ArrayList<java.lang.String>(other.childIds);
        this.childIds = __this__childIds;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
    }

    public addChildGroupsToParentGroup_args deepCopy() {
      return new addChildGroupsToParentGroup_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.childIds = null;
      this.groupId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public addChildGroupsToParentGroup_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public int getChildIdsSize() {
      return (this.childIds == null) ? 0 : this.childIds.size();
    }

    public java.util.Iterator<java.lang.String> getChildIdsIterator() {
      return (this.childIds == null) ? null : this.childIds.iterator();
    }

    public void addToChildIds(java.lang.String elem) {
      if (this.childIds == null) {
        this.childIds = new java.util.ArrayList<java.lang.String>();
      }
      this.childIds.add(elem);
    }

    public java.util.List<java.lang.String> getChildIds() {
      return this.childIds;
    }

    public addChildGroupsToParentGroup_args setChildIds(java.util.List<java.lang.String> childIds) {
      this.childIds = childIds;
      return this;
    }

    public void unsetChildIds() {
      this.childIds = null;
    }

    /** Returns true if field childIds is set (has been assigned a value) and false otherwise */
    public boolean isSetChildIds() {
      return this.childIds != null;
    }

    public void setChildIdsIsSet(boolean value) {
      if (!value) {
        this.childIds = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public addChildGroupsToParentGroup_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case CHILD_IDS:
        if (value == null) {
          unsetChildIds();
        } else {
          setChildIds((java.util.List<java.lang.String>)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case CHILD_IDS:
        return getChildIds();

      case GROUP_ID:
        return getGroupId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case CHILD_IDS:
        return isSetChildIds();
      case GROUP_ID:
        return isSetGroupId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addChildGroupsToParentGroup_args)
        return this.equals((addChildGroupsToParentGroup_args)that);
      return false;
    }

    public boolean equals(addChildGroupsToParentGroup_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_childIds = true && this.isSetChildIds();
      boolean that_present_childIds = true && that.isSetChildIds();
      if (this_present_childIds || that_present_childIds) {
        if (!(this_present_childIds && that_present_childIds))
          return false;
        if (!this.childIds.equals(that.childIds))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetChildIds()) ? 131071 : 524287);
      if (isSetChildIds())
        hashCode = hashCode * 8191 + childIds.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addChildGroupsToParentGroup_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetChildIds()).compareTo(other.isSetChildIds());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetChildIds()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.childIds, other.childIds);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addChildGroupsToParentGroup_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("childIds:");
      if (this.childIds == null) {
        sb.append("null");
      } else {
        sb.append(this.childIds);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (childIds == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'childIds' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 addChildGroupsToParentGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addChildGroupsToParentGroup_argsStandardScheme getScheme() {
        return new addChildGroupsToParentGroup_argsStandardScheme();
      }
    }

    private static class addChildGroupsToParentGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<addChildGroupsToParentGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addChildGroupsToParentGroup_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // CHILD_IDS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list72 = iprot.readListBegin();
                  struct.childIds = new java.util.ArrayList<java.lang.String>(_list72.size);
                  java.lang.String _elem73;
                  for (int _i74 = 0; _i74 < _list72.size; ++_i74)
                  {
                    _elem73 = iprot.readString();
                    struct.childIds.add(_elem73);
                  }
                  iprot.readListEnd();
                }
                struct.setChildIdsIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addChildGroupsToParentGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.childIds != null) {
          oprot.writeFieldBegin(CHILD_IDS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.childIds.size()));
            for (java.lang.String _iter75 : struct.childIds)
            {
              oprot.writeString(_iter75);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addChildGroupsToParentGroup_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addChildGroupsToParentGroup_argsTupleScheme getScheme() {
        return new addChildGroupsToParentGroup_argsTupleScheme();
      }
    }

    private static class addChildGroupsToParentGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<addChildGroupsToParentGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addChildGroupsToParentGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        {
          oprot.writeI32(struct.childIds.size());
          for (java.lang.String _iter76 : struct.childIds)
          {
            oprot.writeString(_iter76);
          }
        }
        oprot.writeString(struct.groupId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addChildGroupsToParentGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list77 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.childIds = new java.util.ArrayList<java.lang.String>(_list77.size);
          java.lang.String _elem78;
          for (int _i79 = 0; _i79 < _list77.size; ++_i79)
          {
            _elem78 = iprot.readString();
            struct.childIds.add(_elem78);
          }
        }
        struct.setChildIdsIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class addChildGroupsToParentGroup_result implements org.apache.thrift.TBase<addChildGroupsToParentGroup_result, addChildGroupsToParentGroup_result._Fields>, java.io.Serializable, Cloneable, Comparable<addChildGroupsToParentGroup_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("addChildGroupsToParentGroup_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new addChildGroupsToParentGroup_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new addChildGroupsToParentGroup_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(addChildGroupsToParentGroup_result.class, metaDataMap);
    }

    public addChildGroupsToParentGroup_result() {
    }

    public addChildGroupsToParentGroup_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public addChildGroupsToParentGroup_result(addChildGroupsToParentGroup_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public addChildGroupsToParentGroup_result deepCopy() {
      return new addChildGroupsToParentGroup_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public addChildGroupsToParentGroup_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public addChildGroupsToParentGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof addChildGroupsToParentGroup_result)
        return this.equals((addChildGroupsToParentGroup_result)that);
      return false;
    }

    public boolean equals(addChildGroupsToParentGroup_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(addChildGroupsToParentGroup_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("addChildGroupsToParentGroup_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class addChildGroupsToParentGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addChildGroupsToParentGroup_resultStandardScheme getScheme() {
        return new addChildGroupsToParentGroup_resultStandardScheme();
      }
    }

    private static class addChildGroupsToParentGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<addChildGroupsToParentGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, addChildGroupsToParentGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, addChildGroupsToParentGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class addChildGroupsToParentGroup_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public addChildGroupsToParentGroup_resultTupleScheme getScheme() {
        return new addChildGroupsToParentGroup_resultTupleScheme();
      }
    }

    private static class addChildGroupsToParentGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<addChildGroupsToParentGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, addChildGroupsToParentGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, addChildGroupsToParentGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class removeChildGroupFromParentGroup_args implements org.apache.thrift.TBase<removeChildGroupFromParentGroup_args, removeChildGroupFromParentGroup_args._Fields>, java.io.Serializable, Cloneable, Comparable<removeChildGroupFromParentGroup_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeChildGroupFromParentGroup_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField CHILD_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("childId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField GROUP_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("groupId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeChildGroupFromParentGroup_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeChildGroupFromParentGroup_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String childId; // required
    public java.lang.String groupId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      CHILD_ID((short)2, "childId"),
      GROUP_ID((short)3, "groupId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // CHILD_ID
            return CHILD_ID;
          case 3: // GROUP_ID
            return GROUP_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.CHILD_ID, new org.apache.thrift.meta_data.FieldMetaData("childId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_ID, new org.apache.thrift.meta_data.FieldMetaData("groupId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeChildGroupFromParentGroup_args.class, metaDataMap);
    }

    public removeChildGroupFromParentGroup_args() {
    }

    public removeChildGroupFromParentGroup_args(
      java.lang.String domainId,
      java.lang.String childId,
      java.lang.String groupId)
    {
      this();
      this.domainId = domainId;
      this.childId = childId;
      this.groupId = groupId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeChildGroupFromParentGroup_args(removeChildGroupFromParentGroup_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetChildId()) {
        this.childId = other.childId;
      }
      if (other.isSetGroupId()) {
        this.groupId = other.groupId;
      }
    }

    public removeChildGroupFromParentGroup_args deepCopy() {
      return new removeChildGroupFromParentGroup_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.childId = null;
      this.groupId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public removeChildGroupFromParentGroup_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getChildId() {
      return this.childId;
    }

    public removeChildGroupFromParentGroup_args setChildId(java.lang.String childId) {
      this.childId = childId;
      return this;
    }

    public void unsetChildId() {
      this.childId = null;
    }

    /** Returns true if field childId is set (has been assigned a value) and false otherwise */
    public boolean isSetChildId() {
      return this.childId != null;
    }

    public void setChildIdIsSet(boolean value) {
      if (!value) {
        this.childId = null;
      }
    }

    public java.lang.String getGroupId() {
      return this.groupId;
    }

    public removeChildGroupFromParentGroup_args setGroupId(java.lang.String groupId) {
      this.groupId = groupId;
      return this;
    }

    public void unsetGroupId() {
      this.groupId = null;
    }

    /** Returns true if field groupId is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupId() {
      return this.groupId != null;
    }

    public void setGroupIdIsSet(boolean value) {
      if (!value) {
        this.groupId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case CHILD_ID:
        if (value == null) {
          unsetChildId();
        } else {
          setChildId((java.lang.String)value);
        }
        break;

      case GROUP_ID:
        if (value == null) {
          unsetGroupId();
        } else {
          setGroupId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case CHILD_ID:
        return getChildId();

      case GROUP_ID:
        return getGroupId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case CHILD_ID:
        return isSetChildId();
      case GROUP_ID:
        return isSetGroupId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeChildGroupFromParentGroup_args)
        return this.equals((removeChildGroupFromParentGroup_args)that);
      return false;
    }

    public boolean equals(removeChildGroupFromParentGroup_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_childId = true && this.isSetChildId();
      boolean that_present_childId = true && that.isSetChildId();
      if (this_present_childId || that_present_childId) {
        if (!(this_present_childId && that_present_childId))
          return false;
        if (!this.childId.equals(that.childId))
          return false;
      }

      boolean this_present_groupId = true && this.isSetGroupId();
      boolean that_present_groupId = true && that.isSetGroupId();
      if (this_present_groupId || that_present_groupId) {
        if (!(this_present_groupId && that_present_groupId))
          return false;
        if (!this.groupId.equals(that.groupId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetChildId()) ? 131071 : 524287);
      if (isSetChildId())
        hashCode = hashCode * 8191 + childId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupId()) ? 131071 : 524287);
      if (isSetGroupId())
        hashCode = hashCode * 8191 + groupId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeChildGroupFromParentGroup_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetChildId()).compareTo(other.isSetChildId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetChildId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.childId, other.childId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupId()).compareTo(other.isSetGroupId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupId, other.groupId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeChildGroupFromParentGroup_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("childId:");
      if (this.childId == null) {
        sb.append("null");
      } else {
        sb.append(this.childId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupId:");
      if (this.groupId == null) {
        sb.append("null");
      } else {
        sb.append(this.groupId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (childId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'childId' was not present! Struct: " + toString());
      }
      if (groupId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 removeChildGroupFromParentGroup_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeChildGroupFromParentGroup_argsStandardScheme getScheme() {
        return new removeChildGroupFromParentGroup_argsStandardScheme();
      }
    }

    private static class removeChildGroupFromParentGroup_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeChildGroupFromParentGroup_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, removeChildGroupFromParentGroup_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // CHILD_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.childId = iprot.readString();
                struct.setChildIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GROUP_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.groupId = iprot.readString();
                struct.setGroupIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeChildGroupFromParentGroup_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.childId != null) {
          oprot.writeFieldBegin(CHILD_ID_FIELD_DESC);
          oprot.writeString(struct.childId);
          oprot.writeFieldEnd();
        }
        if (struct.groupId != null) {
          oprot.writeFieldBegin(GROUP_ID_FIELD_DESC);
          oprot.writeString(struct.groupId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeChildGroupFromParentGroup_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeChildGroupFromParentGroup_argsTupleScheme getScheme() {
        return new removeChildGroupFromParentGroup_argsTupleScheme();
      }
    }

    private static class removeChildGroupFromParentGroup_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeChildGroupFromParentGroup_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, removeChildGroupFromParentGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.childId);
        oprot.writeString(struct.groupId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeChildGroupFromParentGroup_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.childId = iprot.readString();
        struct.setChildIdIsSet(true);
        struct.groupId = iprot.readString();
        struct.setGroupIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class removeChildGroupFromParentGroup_result implements org.apache.thrift.TBase<removeChildGroupFromParentGroup_result, removeChildGroupFromParentGroup_result._Fields>, java.io.Serializable, Cloneable, Comparable<removeChildGroupFromParentGroup_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("removeChildGroupFromParentGroup_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new removeChildGroupFromParentGroup_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new removeChildGroupFromParentGroup_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(removeChildGroupFromParentGroup_result.class, metaDataMap);
    }

    public removeChildGroupFromParentGroup_result() {
    }

    public removeChildGroupFromParentGroup_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public removeChildGroupFromParentGroup_result(removeChildGroupFromParentGroup_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public removeChildGroupFromParentGroup_result deepCopy() {
      return new removeChildGroupFromParentGroup_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public removeChildGroupFromParentGroup_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public removeChildGroupFromParentGroup_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof removeChildGroupFromParentGroup_result)
        return this.equals((removeChildGroupFromParentGroup_result)that);
      return false;
    }

    public boolean equals(removeChildGroupFromParentGroup_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(removeChildGroupFromParentGroup_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("removeChildGroupFromParentGroup_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class removeChildGroupFromParentGroup_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeChildGroupFromParentGroup_resultStandardScheme getScheme() {
        return new removeChildGroupFromParentGroup_resultStandardScheme();
      }
    }

    private static class removeChildGroupFromParentGroup_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<removeChildGroupFromParentGroup_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, removeChildGroupFromParentGroup_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, removeChildGroupFromParentGroup_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class removeChildGroupFromParentGroup_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public removeChildGroupFromParentGroup_resultTupleScheme getScheme() {
        return new removeChildGroupFromParentGroup_resultTupleScheme();
      }
    }

    private static class removeChildGroupFromParentGroup_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<removeChildGroupFromParentGroup_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, removeChildGroupFromParentGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, removeChildGroupFromParentGroup_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getAllMemberGroupsForUser_args implements org.apache.thrift.TBase<getAllMemberGroupsForUser_args, getAllMemberGroupsForUser_args._Fields>, java.io.Serializable, Cloneable, Comparable<getAllMemberGroupsForUser_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllMemberGroupsForUser_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("userId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getAllMemberGroupsForUser_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getAllMemberGroupsForUser_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String userId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      USER_ID((short)2, "userId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // USER_ID
            return USER_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_ID, new org.apache.thrift.meta_data.FieldMetaData("userId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllMemberGroupsForUser_args.class, metaDataMap);
    }

    public getAllMemberGroupsForUser_args() {
    }

    public getAllMemberGroupsForUser_args(
      java.lang.String domainId,
      java.lang.String userId)
    {
      this();
      this.domainId = domainId;
      this.userId = userId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllMemberGroupsForUser_args(getAllMemberGroupsForUser_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetUserId()) {
        this.userId = other.userId;
      }
    }

    public getAllMemberGroupsForUser_args deepCopy() {
      return new getAllMemberGroupsForUser_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.userId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getAllMemberGroupsForUser_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getUserId() {
      return this.userId;
    }

    public getAllMemberGroupsForUser_args setUserId(java.lang.String userId) {
      this.userId = userId;
      return this;
    }

    public void unsetUserId() {
      this.userId = null;
    }

    /** Returns true if field userId is set (has been assigned a value) and false otherwise */
    public boolean isSetUserId() {
      return this.userId != null;
    }

    public void setUserIdIsSet(boolean value) {
      if (!value) {
        this.userId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case USER_ID:
        if (value == null) {
          unsetUserId();
        } else {
          setUserId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case USER_ID:
        return getUserId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case USER_ID:
        return isSetUserId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllMemberGroupsForUser_args)
        return this.equals((getAllMemberGroupsForUser_args)that);
      return false;
    }

    public boolean equals(getAllMemberGroupsForUser_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_userId = true && this.isSetUserId();
      boolean that_present_userId = true && that.isSetUserId();
      if (this_present_userId || that_present_userId) {
        if (!(this_present_userId && that_present_userId))
          return false;
        if (!this.userId.equals(that.userId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserId()) ? 131071 : 524287);
      if (isSetUserId())
        hashCode = hashCode * 8191 + userId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getAllMemberGroupsForUser_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserId()).compareTo(other.isSetUserId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userId, other.userId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getAllMemberGroupsForUser_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userId:");
      if (this.userId == null) {
        sb.append("null");
      } else {
        sb.append(this.userId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (userId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getAllMemberGroupsForUser_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllMemberGroupsForUser_argsStandardScheme getScheme() {
        return new getAllMemberGroupsForUser_argsStandardScheme();
      }
    }

    private static class getAllMemberGroupsForUser_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllMemberGroupsForUser_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllMemberGroupsForUser_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userId = iprot.readString();
                struct.setUserIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAllMemberGroupsForUser_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.userId != null) {
          oprot.writeFieldBegin(USER_ID_FIELD_DESC);
          oprot.writeString(struct.userId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAllMemberGroupsForUser_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllMemberGroupsForUser_argsTupleScheme getScheme() {
        return new getAllMemberGroupsForUser_argsTupleScheme();
      }
    }

    private static class getAllMemberGroupsForUser_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllMemberGroupsForUser_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllMemberGroupsForUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.userId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllMemberGroupsForUser_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.userId = iprot.readString();
        struct.setUserIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getAllMemberGroupsForUser_result implements org.apache.thrift.TBase<getAllMemberGroupsForUser_result, getAllMemberGroupsForUser_result._Fields>, java.io.Serializable, Cloneable, Comparable<getAllMemberGroupsForUser_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getAllMemberGroupsForUser_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getAllMemberGroupsForUser_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getAllMemberGroupsForUser_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.UserGroup.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getAllMemberGroupsForUser_result.class, metaDataMap);
    }

    public getAllMemberGroupsForUser_result() {
    }

    public getAllMemberGroupsForUser_result(
      java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getAllMemberGroupsForUser_result(getAllMemberGroupsForUser_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.UserGroup other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.UserGroup(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getAllMemberGroupsForUser_result deepCopy() {
      return new getAllMemberGroupsForUser_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.UserGroup> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.UserGroup elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getSuccess() {
      return this.success;
    }

    public getAllMemberGroupsForUser_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getAllMemberGroupsForUser_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getAllMemberGroupsForUser_result)
        return this.equals((getAllMemberGroupsForUser_result)that);
      return false;
    }

    public boolean equals(getAllMemberGroupsForUser_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getAllMemberGroupsForUser_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getAllMemberGroupsForUser_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getAllMemberGroupsForUser_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllMemberGroupsForUser_resultStandardScheme getScheme() {
        return new getAllMemberGroupsForUser_resultStandardScheme();
      }
    }

    private static class getAllMemberGroupsForUser_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getAllMemberGroupsForUser_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getAllMemberGroupsForUser_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list80 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list80.size);
                  org.apache.airavata.sharing.registry.models.UserGroup _elem81;
                  for (int _i82 = 0; _i82 < _list80.size; ++_i82)
                  {
                    _elem81 = new org.apache.airavata.sharing.registry.models.UserGroup();
                    _elem81.read(iprot);
                    struct.success.add(_elem81);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getAllMemberGroupsForUser_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter83 : struct.success)
            {
              _iter83.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getAllMemberGroupsForUser_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getAllMemberGroupsForUser_resultTupleScheme getScheme() {
        return new getAllMemberGroupsForUser_resultTupleScheme();
      }
    }

    private static class getAllMemberGroupsForUser_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getAllMemberGroupsForUser_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getAllMemberGroupsForUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter84 : struct.success)
            {
              _iter84.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getAllMemberGroupsForUser_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list85 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list85.size);
            org.apache.airavata.sharing.registry.models.UserGroup _elem86;
            for (int _i87 = 0; _i87 < _list85.size; ++_i87)
            {
              _elem86 = new org.apache.airavata.sharing.registry.models.UserGroup();
              _elem86.read(iprot);
              struct.success.add(_elem86);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class createEntityType_args implements org.apache.thrift.TBase<createEntityType_args, createEntityType_args._Fields>, java.io.Serializable, Cloneable, Comparable<createEntityType_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createEntityType_args");

    private static final org.apache.thrift.protocol.TField ENTITY_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("entityType", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createEntityType_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createEntityType_argsTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.EntityType entityType; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      ENTITY_TYPE((short)1, "entityType");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // ENTITY_TYPE
            return ENTITY_TYPE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.ENTITY_TYPE, new org.apache.thrift.meta_data.FieldMetaData("entityType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.EntityType.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createEntityType_args.class, metaDataMap);
    }

    public createEntityType_args() {
    }

    public createEntityType_args(
      org.apache.airavata.sharing.registry.models.EntityType entityType)
    {
      this();
      this.entityType = entityType;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createEntityType_args(createEntityType_args other) {
      if (other.isSetEntityType()) {
        this.entityType = new org.apache.airavata.sharing.registry.models.EntityType(other.entityType);
      }
    }

    public createEntityType_args deepCopy() {
      return new createEntityType_args(this);
    }

    @Override
    public void clear() {
      this.entityType = null;
    }

    public org.apache.airavata.sharing.registry.models.EntityType getEntityType() {
      return this.entityType;
    }

    public createEntityType_args setEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType) {
      this.entityType = entityType;
      return this;
    }

    public void unsetEntityType() {
      this.entityType = null;
    }

    /** Returns true if field entityType is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityType() {
      return this.entityType != null;
    }

    public void setEntityTypeIsSet(boolean value) {
      if (!value) {
        this.entityType = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case ENTITY_TYPE:
        if (value == null) {
          unsetEntityType();
        } else {
          setEntityType((org.apache.airavata.sharing.registry.models.EntityType)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case ENTITY_TYPE:
        return getEntityType();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case ENTITY_TYPE:
        return isSetEntityType();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createEntityType_args)
        return this.equals((createEntityType_args)that);
      return false;
    }

    public boolean equals(createEntityType_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_entityType = true && this.isSetEntityType();
      boolean that_present_entityType = true && that.isSetEntityType();
      if (this_present_entityType || that_present_entityType) {
        if (!(this_present_entityType && that_present_entityType))
          return false;
        if (!this.entityType.equals(that.entityType))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetEntityType()) ? 131071 : 524287);
      if (isSetEntityType())
        hashCode = hashCode * 8191 + entityType.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createEntityType_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetEntityType()).compareTo(other.isSetEntityType());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityType()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityType, other.entityType);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createEntityType_args(");
      boolean first = true;

      sb.append("entityType:");
      if (this.entityType == null) {
        sb.append("null");
      } else {
        sb.append(this.entityType);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (entityType == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityType' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (entityType != null) {
        entityType.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, java.lang.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 createEntityType_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createEntityType_argsStandardScheme getScheme() {
        return new createEntityType_argsStandardScheme();
      }
    }

    private static class createEntityType_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createEntityType_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // ENTITY_TYPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.entityType = new org.apache.airavata.sharing.registry.models.EntityType();
                struct.entityType.read(iprot);
                struct.setEntityTypeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createEntityType_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.entityType != null) {
          oprot.writeFieldBegin(ENTITY_TYPE_FIELD_DESC);
          struct.entityType.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createEntityType_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createEntityType_argsTupleScheme getScheme() {
        return new createEntityType_argsTupleScheme();
      }
    }

    private static class createEntityType_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createEntityType_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.entityType.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.entityType = new org.apache.airavata.sharing.registry.models.EntityType();
        struct.entityType.read(iprot);
        struct.setEntityTypeIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class createEntityType_result implements org.apache.thrift.TBase<createEntityType_result, createEntityType_result._Fields>, java.io.Serializable, Cloneable, Comparable<createEntityType_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createEntityType_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField DEE_FIELD_DESC = new org.apache.thrift.protocol.TField("dee", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createEntityType_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createEntityType_resultTupleSchemeFactory();

    public java.lang.String success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required
    public org.apache.airavata.sharing.registry.models.DuplicateEntryException dee; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre"),
      DEE((short)2, "dee");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          case 2: // DEE
            return DEE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      tmpMap.put(_Fields.DEE, new org.apache.thrift.meta_data.FieldMetaData("dee", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.DuplicateEntryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createEntityType_result.class, metaDataMap);
    }

    public createEntityType_result() {
    }

    public createEntityType_result(
      java.lang.String success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre,
      org.apache.airavata.sharing.registry.models.DuplicateEntryException dee)
    {
      this();
      this.success = success;
      this.sre = sre;
      this.dee = dee;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createEntityType_result(createEntityType_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
      if (other.isSetDee()) {
        this.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException(other.dee);
      }
    }

    public createEntityType_result deepCopy() {
      return new createEntityType_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
      this.dee = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createEntityType_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public createEntityType_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.DuplicateEntryException getDee() {
      return this.dee;
    }

    public createEntityType_result setDee(org.apache.airavata.sharing.registry.models.DuplicateEntryException dee) {
      this.dee = dee;
      return this;
    }

    public void unsetDee() {
      this.dee = null;
    }

    /** Returns true if field dee is set (has been assigned a value) and false otherwise */
    public boolean isSetDee() {
      return this.dee != null;
    }

    public void setDeeIsSet(boolean value) {
      if (!value) {
        this.dee = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      case DEE:
        if (value == null) {
          unsetDee();
        } else {
          setDee((org.apache.airavata.sharing.registry.models.DuplicateEntryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      case DEE:
        return getDee();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      case DEE:
        return isSetDee();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createEntityType_result)
        return this.equals((createEntityType_result)that);
      return false;
    }

    public boolean equals(createEntityType_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      boolean this_present_dee = true && this.isSetDee();
      boolean that_present_dee = true && that.isSetDee();
      if (this_present_dee || that_present_dee) {
        if (!(this_present_dee && that_present_dee))
          return false;
        if (!this.dee.equals(that.dee))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      hashCode = hashCode * 8191 + ((isSetDee()) ? 131071 : 524287);
      if (isSetDee())
        hashCode = hashCode * 8191 + dee.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createEntityType_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetDee()).compareTo(other.isSetDee());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDee()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dee, other.dee);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createEntityType_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("dee:");
      if (this.dee == null) {
        sb.append("null");
      } else {
        sb.append(this.dee);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 createEntityType_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createEntityType_resultStandardScheme getScheme() {
        return new createEntityType_resultStandardScheme();
      }
    }

    private static class createEntityType_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createEntityType_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createEntityType_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // DEE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException();
                struct.dee.read(iprot);
                struct.setDeeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createEntityType_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.dee != null) {
          oprot.writeFieldBegin(DEE_FIELD_DESC);
          struct.dee.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createEntityType_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createEntityType_resultTupleScheme getScheme() {
        return new createEntityType_resultTupleScheme();
      }
    }

    private static class createEntityType_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createEntityType_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createEntityType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        if (struct.isSetDee()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
        if (struct.isSetDee()) {
          struct.dee.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createEntityType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException();
          struct.dee.read(iprot);
          struct.setDeeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class updateEntityType_args implements org.apache.thrift.TBase<updateEntityType_args, updateEntityType_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateEntityType_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateEntityType_args");

    private static final org.apache.thrift.protocol.TField ENTITY_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("entityType", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateEntityType_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateEntityType_argsTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.EntityType entityType; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      ENTITY_TYPE((short)1, "entityType");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // ENTITY_TYPE
            return ENTITY_TYPE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.ENTITY_TYPE, new org.apache.thrift.meta_data.FieldMetaData("entityType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.EntityType.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateEntityType_args.class, metaDataMap);
    }

    public updateEntityType_args() {
    }

    public updateEntityType_args(
      org.apache.airavata.sharing.registry.models.EntityType entityType)
    {
      this();
      this.entityType = entityType;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateEntityType_args(updateEntityType_args other) {
      if (other.isSetEntityType()) {
        this.entityType = new org.apache.airavata.sharing.registry.models.EntityType(other.entityType);
      }
    }

    public updateEntityType_args deepCopy() {
      return new updateEntityType_args(this);
    }

    @Override
    public void clear() {
      this.entityType = null;
    }

    public org.apache.airavata.sharing.registry.models.EntityType getEntityType() {
      return this.entityType;
    }

    public updateEntityType_args setEntityType(org.apache.airavata.sharing.registry.models.EntityType entityType) {
      this.entityType = entityType;
      return this;
    }

    public void unsetEntityType() {
      this.entityType = null;
    }

    /** Returns true if field entityType is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityType() {
      return this.entityType != null;
    }

    public void setEntityTypeIsSet(boolean value) {
      if (!value) {
        this.entityType = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case ENTITY_TYPE:
        if (value == null) {
          unsetEntityType();
        } else {
          setEntityType((org.apache.airavata.sharing.registry.models.EntityType)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case ENTITY_TYPE:
        return getEntityType();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case ENTITY_TYPE:
        return isSetEntityType();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateEntityType_args)
        return this.equals((updateEntityType_args)that);
      return false;
    }

    public boolean equals(updateEntityType_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_entityType = true && this.isSetEntityType();
      boolean that_present_entityType = true && that.isSetEntityType();
      if (this_present_entityType || that_present_entityType) {
        if (!(this_present_entityType && that_present_entityType))
          return false;
        if (!this.entityType.equals(that.entityType))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetEntityType()) ? 131071 : 524287);
      if (isSetEntityType())
        hashCode = hashCode * 8191 + entityType.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateEntityType_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetEntityType()).compareTo(other.isSetEntityType());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityType()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityType, other.entityType);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateEntityType_args(");
      boolean first = true;

      sb.append("entityType:");
      if (this.entityType == null) {
        sb.append("null");
      } else {
        sb.append(this.entityType);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (entityType == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityType' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (entityType != null) {
        entityType.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, java.lang.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 updateEntityType_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateEntityType_argsStandardScheme getScheme() {
        return new updateEntityType_argsStandardScheme();
      }
    }

    private static class updateEntityType_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateEntityType_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // ENTITY_TYPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.entityType = new org.apache.airavata.sharing.registry.models.EntityType();
                struct.entityType.read(iprot);
                struct.setEntityTypeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateEntityType_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.entityType != null) {
          oprot.writeFieldBegin(ENTITY_TYPE_FIELD_DESC);
          struct.entityType.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateEntityType_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateEntityType_argsTupleScheme getScheme() {
        return new updateEntityType_argsTupleScheme();
      }
    }

    private static class updateEntityType_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateEntityType_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.entityType.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.entityType = new org.apache.airavata.sharing.registry.models.EntityType();
        struct.entityType.read(iprot);
        struct.setEntityTypeIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class updateEntityType_result implements org.apache.thrift.TBase<updateEntityType_result, updateEntityType_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateEntityType_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateEntityType_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateEntityType_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateEntityType_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateEntityType_result.class, metaDataMap);
    }

    public updateEntityType_result() {
    }

    public updateEntityType_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateEntityType_result(updateEntityType_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public updateEntityType_result deepCopy() {
      return new updateEntityType_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateEntityType_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public updateEntityType_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateEntityType_result)
        return this.equals((updateEntityType_result)that);
      return false;
    }

    public boolean equals(updateEntityType_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateEntityType_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateEntityType_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateEntityType_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateEntityType_resultStandardScheme getScheme() {
        return new updateEntityType_resultStandardScheme();
      }
    }

    private static class updateEntityType_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateEntityType_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateEntityType_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateEntityType_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateEntityType_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateEntityType_resultTupleScheme getScheme() {
        return new updateEntityType_resultTupleScheme();
      }
    }

    private static class updateEntityType_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateEntityType_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateEntityType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateEntityType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isEntityTypeExists_args implements org.apache.thrift.TBase<isEntityTypeExists_args, isEntityTypeExists_args._Fields>, java.io.Serializable, Cloneable, Comparable<isEntityTypeExists_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isEntityTypeExists_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityTypeId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isEntityTypeExists_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isEntityTypeExists_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_TYPE_ID((short)2, "entityTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_TYPE_ID
            return ENTITY_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("entityTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isEntityTypeExists_args.class, metaDataMap);
    }

    public isEntityTypeExists_args() {
    }

    public isEntityTypeExists_args(
      java.lang.String domainId,
      java.lang.String entityTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityTypeId = entityTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isEntityTypeExists_args(isEntityTypeExists_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityTypeId()) {
        this.entityTypeId = other.entityTypeId;
      }
    }

    public isEntityTypeExists_args deepCopy() {
      return new isEntityTypeExists_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public isEntityTypeExists_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityTypeId() {
      return this.entityTypeId;
    }

    public isEntityTypeExists_args setEntityTypeId(java.lang.String entityTypeId) {
      this.entityTypeId = entityTypeId;
      return this;
    }

    public void unsetEntityTypeId() {
      this.entityTypeId = null;
    }

    /** Returns true if field entityTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityTypeId() {
      return this.entityTypeId != null;
    }

    public void setEntityTypeIdIsSet(boolean value) {
      if (!value) {
        this.entityTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_TYPE_ID:
        if (value == null) {
          unsetEntityTypeId();
        } else {
          setEntityTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_TYPE_ID:
        return getEntityTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_TYPE_ID:
        return isSetEntityTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isEntityTypeExists_args)
        return this.equals((isEntityTypeExists_args)that);
      return false;
    }

    public boolean equals(isEntityTypeExists_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityTypeId = true && this.isSetEntityTypeId();
      boolean that_present_entityTypeId = true && that.isSetEntityTypeId();
      if (this_present_entityTypeId || that_present_entityTypeId) {
        if (!(this_present_entityTypeId && that_present_entityTypeId))
          return false;
        if (!this.entityTypeId.equals(that.entityTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityTypeId()) ? 131071 : 524287);
      if (isSetEntityTypeId())
        hashCode = hashCode * 8191 + entityTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isEntityTypeExists_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityTypeId()).compareTo(other.isSetEntityTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityTypeId, other.entityTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isEntityTypeExists_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityTypeId:");
      if (this.entityTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 isEntityTypeExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isEntityTypeExists_argsStandardScheme getScheme() {
        return new isEntityTypeExists_argsStandardScheme();
      }
    }

    private static class isEntityTypeExists_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isEntityTypeExists_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isEntityTypeExists_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityTypeId = iprot.readString();
                struct.setEntityTypeIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isEntityTypeExists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityTypeId != null) {
          oprot.writeFieldBegin(ENTITY_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.entityTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isEntityTypeExists_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isEntityTypeExists_argsTupleScheme getScheme() {
        return new isEntityTypeExists_argsTupleScheme();
      }
    }

    private static class isEntityTypeExists_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isEntityTypeExists_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isEntityTypeExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isEntityTypeExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityTypeId = iprot.readString();
        struct.setEntityTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isEntityTypeExists_result implements org.apache.thrift.TBase<isEntityTypeExists_result, isEntityTypeExists_result._Fields>, java.io.Serializable, Cloneable, Comparable<isEntityTypeExists_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isEntityTypeExists_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isEntityTypeExists_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isEntityTypeExists_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isEntityTypeExists_result.class, metaDataMap);
    }

    public isEntityTypeExists_result() {
    }

    public isEntityTypeExists_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isEntityTypeExists_result(isEntityTypeExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public isEntityTypeExists_result deepCopy() {
      return new isEntityTypeExists_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isEntityTypeExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public isEntityTypeExists_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isEntityTypeExists_result)
        return this.equals((isEntityTypeExists_result)that);
      return false;
    }

    public boolean equals(isEntityTypeExists_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isEntityTypeExists_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isEntityTypeExists_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class isEntityTypeExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isEntityTypeExists_resultStandardScheme getScheme() {
        return new isEntityTypeExists_resultStandardScheme();
      }
    }

    private static class isEntityTypeExists_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isEntityTypeExists_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isEntityTypeExists_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isEntityTypeExists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isEntityTypeExists_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isEntityTypeExists_resultTupleScheme getScheme() {
        return new isEntityTypeExists_resultTupleScheme();
      }
    }

    private static class isEntityTypeExists_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isEntityTypeExists_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isEntityTypeExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isEntityTypeExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deleteEntityType_args implements org.apache.thrift.TBase<deleteEntityType_args, deleteEntityType_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteEntityType_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteEntityType_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityTypeId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteEntityType_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteEntityType_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_TYPE_ID((short)2, "entityTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_TYPE_ID
            return ENTITY_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("entityTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteEntityType_args.class, metaDataMap);
    }

    public deleteEntityType_args() {
    }

    public deleteEntityType_args(
      java.lang.String domainId,
      java.lang.String entityTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityTypeId = entityTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteEntityType_args(deleteEntityType_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityTypeId()) {
        this.entityTypeId = other.entityTypeId;
      }
    }

    public deleteEntityType_args deepCopy() {
      return new deleteEntityType_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public deleteEntityType_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityTypeId() {
      return this.entityTypeId;
    }

    public deleteEntityType_args setEntityTypeId(java.lang.String entityTypeId) {
      this.entityTypeId = entityTypeId;
      return this;
    }

    public void unsetEntityTypeId() {
      this.entityTypeId = null;
    }

    /** Returns true if field entityTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityTypeId() {
      return this.entityTypeId != null;
    }

    public void setEntityTypeIdIsSet(boolean value) {
      if (!value) {
        this.entityTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_TYPE_ID:
        if (value == null) {
          unsetEntityTypeId();
        } else {
          setEntityTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_TYPE_ID:
        return getEntityTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_TYPE_ID:
        return isSetEntityTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteEntityType_args)
        return this.equals((deleteEntityType_args)that);
      return false;
    }

    public boolean equals(deleteEntityType_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityTypeId = true && this.isSetEntityTypeId();
      boolean that_present_entityTypeId = true && that.isSetEntityTypeId();
      if (this_present_entityTypeId || that_present_entityTypeId) {
        if (!(this_present_entityTypeId && that_present_entityTypeId))
          return false;
        if (!this.entityTypeId.equals(that.entityTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityTypeId()) ? 131071 : 524287);
      if (isSetEntityTypeId())
        hashCode = hashCode * 8191 + entityTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteEntityType_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityTypeId()).compareTo(other.isSetEntityTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityTypeId, other.entityTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteEntityType_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityTypeId:");
      if (this.entityTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 deleteEntityType_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteEntityType_argsStandardScheme getScheme() {
        return new deleteEntityType_argsStandardScheme();
      }
    }

    private static class deleteEntityType_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteEntityType_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteEntityType_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityTypeId = iprot.readString();
                struct.setEntityTypeIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteEntityType_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityTypeId != null) {
          oprot.writeFieldBegin(ENTITY_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.entityTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteEntityType_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteEntityType_argsTupleScheme getScheme() {
        return new deleteEntityType_argsTupleScheme();
      }
    }

    private static class deleteEntityType_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteEntityType_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityTypeId = iprot.readString();
        struct.setEntityTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deleteEntityType_result implements org.apache.thrift.TBase<deleteEntityType_result, deleteEntityType_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteEntityType_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteEntityType_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteEntityType_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteEntityType_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteEntityType_result.class, metaDataMap);
    }

    public deleteEntityType_result() {
    }

    public deleteEntityType_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteEntityType_result(deleteEntityType_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public deleteEntityType_result deepCopy() {
      return new deleteEntityType_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteEntityType_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public deleteEntityType_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteEntityType_result)
        return this.equals((deleteEntityType_result)that);
      return false;
    }

    public boolean equals(deleteEntityType_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteEntityType_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteEntityType_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteEntityType_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteEntityType_resultStandardScheme getScheme() {
        return new deleteEntityType_resultStandardScheme();
      }
    }

    private static class deleteEntityType_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteEntityType_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteEntityType_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteEntityType_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteEntityType_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteEntityType_resultTupleScheme getScheme() {
        return new deleteEntityType_resultTupleScheme();
      }
    }

    private static class deleteEntityType_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteEntityType_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteEntityType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteEntityType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getEntityType_args implements org.apache.thrift.TBase<getEntityType_args, getEntityType_args._Fields>, java.io.Serializable, Cloneable, Comparable<getEntityType_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getEntityType_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityTypeId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getEntityType_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getEntityType_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_TYPE_ID((short)2, "entityTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_TYPE_ID
            return ENTITY_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("entityTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getEntityType_args.class, metaDataMap);
    }

    public getEntityType_args() {
    }

    public getEntityType_args(
      java.lang.String domainId,
      java.lang.String entityTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityTypeId = entityTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getEntityType_args(getEntityType_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityTypeId()) {
        this.entityTypeId = other.entityTypeId;
      }
    }

    public getEntityType_args deepCopy() {
      return new getEntityType_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getEntityType_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityTypeId() {
      return this.entityTypeId;
    }

    public getEntityType_args setEntityTypeId(java.lang.String entityTypeId) {
      this.entityTypeId = entityTypeId;
      return this;
    }

    public void unsetEntityTypeId() {
      this.entityTypeId = null;
    }

    /** Returns true if field entityTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityTypeId() {
      return this.entityTypeId != null;
    }

    public void setEntityTypeIdIsSet(boolean value) {
      if (!value) {
        this.entityTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_TYPE_ID:
        if (value == null) {
          unsetEntityTypeId();
        } else {
          setEntityTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_TYPE_ID:
        return getEntityTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_TYPE_ID:
        return isSetEntityTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getEntityType_args)
        return this.equals((getEntityType_args)that);
      return false;
    }

    public boolean equals(getEntityType_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityTypeId = true && this.isSetEntityTypeId();
      boolean that_present_entityTypeId = true && that.isSetEntityTypeId();
      if (this_present_entityTypeId || that_present_entityTypeId) {
        if (!(this_present_entityTypeId && that_present_entityTypeId))
          return false;
        if (!this.entityTypeId.equals(that.entityTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityTypeId()) ? 131071 : 524287);
      if (isSetEntityTypeId())
        hashCode = hashCode * 8191 + entityTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getEntityType_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityTypeId()).compareTo(other.isSetEntityTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityTypeId, other.entityTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getEntityType_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityTypeId:");
      if (this.entityTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getEntityType_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntityType_argsStandardScheme getScheme() {
        return new getEntityType_argsStandardScheme();
      }
    }

    private static class getEntityType_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getEntityType_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getEntityType_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityTypeId = iprot.readString();
                struct.setEntityTypeIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getEntityType_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityTypeId != null) {
          oprot.writeFieldBegin(ENTITY_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.entityTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getEntityType_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntityType_argsTupleScheme getScheme() {
        return new getEntityType_argsTupleScheme();
      }
    }

    private static class getEntityType_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getEntityType_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getEntityType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityTypeId = iprot.readString();
        struct.setEntityTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getEntityType_result implements org.apache.thrift.TBase<getEntityType_result, getEntityType_result._Fields>, java.io.Serializable, Cloneable, Comparable<getEntityType_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getEntityType_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getEntityType_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getEntityType_resultTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.EntityType success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.EntityType.class)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getEntityType_result.class, metaDataMap);
    }

    public getEntityType_result() {
    }

    public getEntityType_result(
      org.apache.airavata.sharing.registry.models.EntityType success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getEntityType_result(getEntityType_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.sharing.registry.models.EntityType(other.success);
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getEntityType_result deepCopy() {
      return new getEntityType_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public org.apache.airavata.sharing.registry.models.EntityType getSuccess() {
      return this.success;
    }

    public getEntityType_result setSuccess(org.apache.airavata.sharing.registry.models.EntityType success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getEntityType_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.sharing.registry.models.EntityType)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getEntityType_result)
        return this.equals((getEntityType_result)that);
      return false;
    }

    public boolean equals(getEntityType_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getEntityType_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getEntityType_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.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, java.lang.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 getEntityType_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntityType_resultStandardScheme getScheme() {
        return new getEntityType_resultStandardScheme();
      }
    }

    private static class getEntityType_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getEntityType_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getEntityType_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.sharing.registry.models.EntityType();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getEntityType_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getEntityType_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntityType_resultTupleScheme getScheme() {
        return new getEntityType_resultTupleScheme();
      }
    }

    private static class getEntityType_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getEntityType_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getEntityType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getEntityType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.sharing.registry.models.EntityType();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getEntityTypes_args implements org.apache.thrift.TBase<getEntityTypes_args, getEntityTypes_args._Fields>, java.io.Serializable, Cloneable, Comparable<getEntityTypes_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getEntityTypes_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)2);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getEntityTypes_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getEntityTypes_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public int offset; // required
    public int limit; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      OFFSET((short)2, "offset"),
      LIMIT((short)3, "limit");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // OFFSET
            return OFFSET;
          case 3: // LIMIT
            return LIMIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __OFFSET_ISSET_ID = 0;
    private static final int __LIMIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getEntityTypes_args.class, metaDataMap);
    }

    public getEntityTypes_args() {
    }

    public getEntityTypes_args(
      java.lang.String domainId,
      int offset,
      int limit)
    {
      this();
      this.domainId = domainId;
      this.offset = offset;
      setOffsetIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getEntityTypes_args(getEntityTypes_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      this.offset = other.offset;
      this.limit = other.limit;
    }

    public getEntityTypes_args deepCopy() {
      return new getEntityTypes_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      setOffsetIsSet(false);
      this.offset = 0;
      setLimitIsSet(false);
      this.limit = 0;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getEntityTypes_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public int getOffset() {
      return this.offset;
    }

    public getEntityTypes_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public int getLimit() {
      return this.limit;
    }

    public getEntityTypes_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((java.lang.Integer)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case OFFSET:
        return getOffset();

      case LIMIT:
        return getLimit();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case OFFSET:
        return isSetOffset();
      case LIMIT:
        return isSetLimit();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getEntityTypes_args)
        return this.equals((getEntityTypes_args)that);
      return false;
    }

    public boolean equals(getEntityTypes_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + offset;

      hashCode = hashCode * 8191 + limit;

      return hashCode;
    }

    @Override
    public int compareTo(getEntityTypes_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getEntityTypes_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getEntityTypes_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntityTypes_argsStandardScheme getScheme() {
        return new getEntityTypes_argsStandardScheme();
      }
    }

    private static class getEntityTypes_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getEntityTypes_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getEntityTypes_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getEntityTypes_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getEntityTypes_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntityTypes_argsTupleScheme getScheme() {
        return new getEntityTypes_argsTupleScheme();
      }
    }

    private static class getEntityTypes_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getEntityTypes_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getEntityTypes_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeI32(struct.offset);
        oprot.writeI32(struct.limit);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getEntityTypes_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getEntityTypes_result implements org.apache.thrift.TBase<getEntityTypes_result, getEntityTypes_result._Fields>, java.io.Serializable, Cloneable, Comparable<getEntityTypes_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getEntityTypes_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getEntityTypes_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getEntityTypes_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.EntityType> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.EntityType.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getEntityTypes_result.class, metaDataMap);
    }

    public getEntityTypes_result() {
    }

    public getEntityTypes_result(
      java.util.List<org.apache.airavata.sharing.registry.models.EntityType> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getEntityTypes_result(getEntityTypes_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.EntityType> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.EntityType>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.EntityType other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.EntityType(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getEntityTypes_result deepCopy() {
      return new getEntityTypes_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.EntityType> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.EntityType elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.EntityType>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.EntityType> getSuccess() {
      return this.success;
    }

    public getEntityTypes_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.EntityType> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getEntityTypes_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.EntityType>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getEntityTypes_result)
        return this.equals((getEntityTypes_result)that);
      return false;
    }

    public boolean equals(getEntityTypes_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getEntityTypes_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getEntityTypes_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getEntityTypes_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntityTypes_resultStandardScheme getScheme() {
        return new getEntityTypes_resultStandardScheme();
      }
    }

    private static class getEntityTypes_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getEntityTypes_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getEntityTypes_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list88 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.EntityType>(_list88.size);
                  org.apache.airavata.sharing.registry.models.EntityType _elem89;
                  for (int _i90 = 0; _i90 < _list88.size; ++_i90)
                  {
                    _elem89 = new org.apache.airavata.sharing.registry.models.EntityType();
                    _elem89.read(iprot);
                    struct.success.add(_elem89);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getEntityTypes_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.EntityType _iter91 : struct.success)
            {
              _iter91.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getEntityTypes_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntityTypes_resultTupleScheme getScheme() {
        return new getEntityTypes_resultTupleScheme();
      }
    }

    private static class getEntityTypes_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getEntityTypes_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getEntityTypes_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.EntityType _iter92 : struct.success)
            {
              _iter92.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getEntityTypes_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list93 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.EntityType>(_list93.size);
            org.apache.airavata.sharing.registry.models.EntityType _elem94;
            for (int _i95 = 0; _i95 < _list93.size; ++_i95)
            {
              _elem94 = new org.apache.airavata.sharing.registry.models.EntityType();
              _elem94.read(iprot);
              struct.success.add(_elem94);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class createEntity_args implements org.apache.thrift.TBase<createEntity_args, createEntity_args._Fields>, java.io.Serializable, Cloneable, Comparable<createEntity_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createEntity_args");

    private static final org.apache.thrift.protocol.TField ENTITY_FIELD_DESC = new org.apache.thrift.protocol.TField("entity", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createEntity_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createEntity_argsTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.Entity entity; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      ENTITY((short)1, "entity");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // ENTITY
            return ENTITY;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.ENTITY, new org.apache.thrift.meta_data.FieldMetaData("entity", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.Entity.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createEntity_args.class, metaDataMap);
    }

    public createEntity_args() {
    }

    public createEntity_args(
      org.apache.airavata.sharing.registry.models.Entity entity)
    {
      this();
      this.entity = entity;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createEntity_args(createEntity_args other) {
      if (other.isSetEntity()) {
        this.entity = new org.apache.airavata.sharing.registry.models.Entity(other.entity);
      }
    }

    public createEntity_args deepCopy() {
      return new createEntity_args(this);
    }

    @Override
    public void clear() {
      this.entity = null;
    }

    public org.apache.airavata.sharing.registry.models.Entity getEntity() {
      return this.entity;
    }

    public createEntity_args setEntity(org.apache.airavata.sharing.registry.models.Entity entity) {
      this.entity = entity;
      return this;
    }

    public void unsetEntity() {
      this.entity = null;
    }

    /** Returns true if field entity is set (has been assigned a value) and false otherwise */
    public boolean isSetEntity() {
      return this.entity != null;
    }

    public void setEntityIsSet(boolean value) {
      if (!value) {
        this.entity = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case ENTITY:
        if (value == null) {
          unsetEntity();
        } else {
          setEntity((org.apache.airavata.sharing.registry.models.Entity)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case ENTITY:
        return getEntity();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case ENTITY:
        return isSetEntity();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createEntity_args)
        return this.equals((createEntity_args)that);
      return false;
    }

    public boolean equals(createEntity_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_entity = true && this.isSetEntity();
      boolean that_present_entity = true && that.isSetEntity();
      if (this_present_entity || that_present_entity) {
        if (!(this_present_entity && that_present_entity))
          return false;
        if (!this.entity.equals(that.entity))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetEntity()) ? 131071 : 524287);
      if (isSetEntity())
        hashCode = hashCode * 8191 + entity.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createEntity_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetEntity()).compareTo(other.isSetEntity());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntity()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entity, other.entity);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createEntity_args(");
      boolean first = true;

      sb.append("entity:");
      if (this.entity == null) {
        sb.append("null");
      } else {
        sb.append(this.entity);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (entity == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entity' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (entity != null) {
        entity.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, java.lang.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 createEntity_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createEntity_argsStandardScheme getScheme() {
        return new createEntity_argsStandardScheme();
      }
    }

    private static class createEntity_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createEntity_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // ENTITY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.entity = new org.apache.airavata.sharing.registry.models.Entity();
                struct.entity.read(iprot);
                struct.setEntityIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createEntity_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.entity != null) {
          oprot.writeFieldBegin(ENTITY_FIELD_DESC);
          struct.entity.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createEntity_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createEntity_argsTupleScheme getScheme() {
        return new createEntity_argsTupleScheme();
      }
    }

    private static class createEntity_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createEntity_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.entity.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.entity = new org.apache.airavata.sharing.registry.models.Entity();
        struct.entity.read(iprot);
        struct.setEntityIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class createEntity_result implements org.apache.thrift.TBase<createEntity_result, createEntity_result._Fields>, java.io.Serializable, Cloneable, Comparable<createEntity_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createEntity_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createEntity_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createEntity_resultTupleSchemeFactory();

    public java.lang.String success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createEntity_result.class, metaDataMap);
    }

    public createEntity_result() {
    }

    public createEntity_result(
      java.lang.String success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createEntity_result(createEntity_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public createEntity_result deepCopy() {
      return new createEntity_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createEntity_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public createEntity_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createEntity_result)
        return this.equals((createEntity_result)that);
      return false;
    }

    public boolean equals(createEntity_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createEntity_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createEntity_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 createEntity_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createEntity_resultStandardScheme getScheme() {
        return new createEntity_resultStandardScheme();
      }
    }

    private static class createEntity_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createEntity_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createEntity_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createEntity_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createEntity_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createEntity_resultTupleScheme getScheme() {
        return new createEntity_resultTupleScheme();
      }
    }

    private static class createEntity_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createEntity_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createEntity_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createEntity_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class updateEntity_args implements org.apache.thrift.TBase<updateEntity_args, updateEntity_args._Fields>, java.io.Serializable, Cloneable, Comparable<updateEntity_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateEntity_args");

    private static final org.apache.thrift.protocol.TField ENTITY_FIELD_DESC = new org.apache.thrift.protocol.TField("entity", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateEntity_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateEntity_argsTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.Entity entity; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      ENTITY((short)1, "entity");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // ENTITY
            return ENTITY;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.ENTITY, new org.apache.thrift.meta_data.FieldMetaData("entity", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.Entity.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateEntity_args.class, metaDataMap);
    }

    public updateEntity_args() {
    }

    public updateEntity_args(
      org.apache.airavata.sharing.registry.models.Entity entity)
    {
      this();
      this.entity = entity;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateEntity_args(updateEntity_args other) {
      if (other.isSetEntity()) {
        this.entity = new org.apache.airavata.sharing.registry.models.Entity(other.entity);
      }
    }

    public updateEntity_args deepCopy() {
      return new updateEntity_args(this);
    }

    @Override
    public void clear() {
      this.entity = null;
    }

    public org.apache.airavata.sharing.registry.models.Entity getEntity() {
      return this.entity;
    }

    public updateEntity_args setEntity(org.apache.airavata.sharing.registry.models.Entity entity) {
      this.entity = entity;
      return this;
    }

    public void unsetEntity() {
      this.entity = null;
    }

    /** Returns true if field entity is set (has been assigned a value) and false otherwise */
    public boolean isSetEntity() {
      return this.entity != null;
    }

    public void setEntityIsSet(boolean value) {
      if (!value) {
        this.entity = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case ENTITY:
        if (value == null) {
          unsetEntity();
        } else {
          setEntity((org.apache.airavata.sharing.registry.models.Entity)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case ENTITY:
        return getEntity();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case ENTITY:
        return isSetEntity();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateEntity_args)
        return this.equals((updateEntity_args)that);
      return false;
    }

    public boolean equals(updateEntity_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_entity = true && this.isSetEntity();
      boolean that_present_entity = true && that.isSetEntity();
      if (this_present_entity || that_present_entity) {
        if (!(this_present_entity && that_present_entity))
          return false;
        if (!this.entity.equals(that.entity))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetEntity()) ? 131071 : 524287);
      if (isSetEntity())
        hashCode = hashCode * 8191 + entity.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateEntity_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetEntity()).compareTo(other.isSetEntity());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntity()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entity, other.entity);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateEntity_args(");
      boolean first = true;

      sb.append("entity:");
      if (this.entity == null) {
        sb.append("null");
      } else {
        sb.append(this.entity);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (entity == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entity' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (entity != null) {
        entity.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, java.lang.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 updateEntity_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateEntity_argsStandardScheme getScheme() {
        return new updateEntity_argsStandardScheme();
      }
    }

    private static class updateEntity_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateEntity_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TField schemeField;
        iprot.readStructBegin();
        while (true)
        {
          schemeField = iprot.readFieldBegin();
          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
            break;
          }
          switch (schemeField.id) {
            case 1: // ENTITY
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.entity = new org.apache.airavata.sharing.registry.models.Entity();
                struct.entity.read(iprot);
                struct.setEntityIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateEntity_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.entity != null) {
          oprot.writeFieldBegin(ENTITY_FIELD_DESC);
          struct.entity.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateEntity_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateEntity_argsTupleScheme getScheme() {
        return new updateEntity_argsTupleScheme();
      }
    }

    private static class updateEntity_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateEntity_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.entity.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.entity = new org.apache.airavata.sharing.registry.models.Entity();
        struct.entity.read(iprot);
        struct.setEntityIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class updateEntity_result implements org.apache.thrift.TBase<updateEntity_result, updateEntity_result._Fields>, java.io.Serializable, Cloneable, Comparable<updateEntity_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updateEntity_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updateEntity_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updateEntity_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updateEntity_result.class, metaDataMap);
    }

    public updateEntity_result() {
    }

    public updateEntity_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updateEntity_result(updateEntity_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public updateEntity_result deepCopy() {
      return new updateEntity_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updateEntity_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public updateEntity_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updateEntity_result)
        return this.equals((updateEntity_result)that);
      return false;
    }

    public boolean equals(updateEntity_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updateEntity_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updateEntity_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updateEntity_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateEntity_resultStandardScheme getScheme() {
        return new updateEntity_resultStandardScheme();
      }
    }

    private static class updateEntity_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updateEntity_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updateEntity_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updateEntity_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updateEntity_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updateEntity_resultTupleScheme getScheme() {
        return new updateEntity_resultTupleScheme();
      }
    }

    private static class updateEntity_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updateEntity_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updateEntity_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updateEntity_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isEntityExists_args implements org.apache.thrift.TBase<isEntityExists_args, isEntityExists_args._Fields>, java.io.Serializable, Cloneable, Comparable<isEntityExists_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isEntityExists_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isEntityExists_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isEntityExists_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isEntityExists_args.class, metaDataMap);
    }

    public isEntityExists_args() {
    }

    public isEntityExists_args(
      java.lang.String domainId,
      java.lang.String entityId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isEntityExists_args(isEntityExists_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
    }

    public isEntityExists_args deepCopy() {
      return new isEntityExists_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public isEntityExists_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public isEntityExists_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isEntityExists_args)
        return this.equals((isEntityExists_args)that);
      return false;
    }

    public boolean equals(isEntityExists_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isEntityExists_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isEntityExists_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 isEntityExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isEntityExists_argsStandardScheme getScheme() {
        return new isEntityExists_argsStandardScheme();
      }
    }

    private static class isEntityExists_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isEntityExists_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isEntityExists_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isEntityExists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isEntityExists_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isEntityExists_argsTupleScheme getScheme() {
        return new isEntityExists_argsTupleScheme();
      }
    }

    private static class isEntityExists_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isEntityExists_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isEntityExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isEntityExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isEntityExists_result implements org.apache.thrift.TBase<isEntityExists_result, isEntityExists_result._Fields>, java.io.Serializable, Cloneable, Comparable<isEntityExists_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isEntityExists_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isEntityExists_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isEntityExists_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isEntityExists_result.class, metaDataMap);
    }

    public isEntityExists_result() {
    }

    public isEntityExists_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isEntityExists_result(isEntityExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public isEntityExists_result deepCopy() {
      return new isEntityExists_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isEntityExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public isEntityExists_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isEntityExists_result)
        return this.equals((isEntityExists_result)that);
      return false;
    }

    public boolean equals(isEntityExists_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isEntityExists_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isEntityExists_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class isEntityExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isEntityExists_resultStandardScheme getScheme() {
        return new isEntityExists_resultStandardScheme();
      }
    }

    private static class isEntityExists_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isEntityExists_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isEntityExists_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isEntityExists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isEntityExists_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isEntityExists_resultTupleScheme getScheme() {
        return new isEntityExists_resultTupleScheme();
      }
    }

    private static class isEntityExists_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isEntityExists_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isEntityExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isEntityExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deleteEntity_args implements org.apache.thrift.TBase<deleteEntity_args, deleteEntity_args._Fields>, java.io.Serializable, Cloneable, Comparable<deleteEntity_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteEntity_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteEntity_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteEntity_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteEntity_args.class, metaDataMap);
    }

    public deleteEntity_args() {
    }

    public deleteEntity_args(
      java.lang.String domainId,
      java.lang.String entityId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteEntity_args(deleteEntity_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
    }

    public deleteEntity_args deepCopy() {
      return new deleteEntity_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public deleteEntity_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public deleteEntity_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteEntity_args)
        return this.equals((deleteEntity_args)that);
      return false;
    }

    public boolean equals(deleteEntity_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteEntity_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteEntity_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 deleteEntity_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteEntity_argsStandardScheme getScheme() {
        return new deleteEntity_argsStandardScheme();
      }
    }

    private static class deleteEntity_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteEntity_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteEntity_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteEntity_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteEntity_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteEntity_argsTupleScheme getScheme() {
        return new deleteEntity_argsTupleScheme();
      }
    }

    private static class deleteEntity_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteEntity_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deleteEntity_result implements org.apache.thrift.TBase<deleteEntity_result, deleteEntity_result._Fields>, java.io.Serializable, Cloneable, Comparable<deleteEntity_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deleteEntity_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deleteEntity_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deleteEntity_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deleteEntity_result.class, metaDataMap);
    }

    public deleteEntity_result() {
    }

    public deleteEntity_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deleteEntity_result(deleteEntity_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public deleteEntity_result deepCopy() {
      return new deleteEntity_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deleteEntity_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public deleteEntity_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deleteEntity_result)
        return this.equals((deleteEntity_result)that);
      return false;
    }

    public boolean equals(deleteEntity_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deleteEntity_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deleteEntity_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deleteEntity_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteEntity_resultStandardScheme getScheme() {
        return new deleteEntity_resultStandardScheme();
      }
    }

    private static class deleteEntity_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deleteEntity_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deleteEntity_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deleteEntity_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deleteEntity_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deleteEntity_resultTupleScheme getScheme() {
        return new deleteEntity_resultTupleScheme();
      }
    }

    private static class deleteEntity_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deleteEntity_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deleteEntity_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deleteEntity_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getEntity_args implements org.apache.thrift.TBase<getEntity_args, getEntity_args._Fields>, java.io.Serializable, Cloneable, Comparable<getEntity_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getEntity_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getEntity_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getEntity_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getEntity_args.class, metaDataMap);
    }

    public getEntity_args() {
    }

    public getEntity_args(
      java.lang.String domainId,
      java.lang.String entityId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getEntity_args(getEntity_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
    }

    public getEntity_args deepCopy() {
      return new getEntity_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getEntity_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public getEntity_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getEntity_args)
        return this.equals((getEntity_args)that);
      return false;
    }

    public boolean equals(getEntity_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getEntity_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getEntity_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getEntity_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntity_argsStandardScheme getScheme() {
        return new getEntity_argsStandardScheme();
      }
    }

    private static class getEntity_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getEntity_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getEntity_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            default:
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
          }
          iprot.readFieldEnd();
        }
        iprot.readStructEnd();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getEntity_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getEntity_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntity_argsTupleScheme getScheme() {
        return new getEntity_argsTupleScheme();
      }
    }

    private static class getEntity_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getEntity_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getEntity_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getEntity_result implements org.apache.thrift.TBase<getEntity_result, getEntity_result._Fields>, java.io.Serializable, Cloneable, Comparable<getEntity_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getEntity_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getEntity_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getEntity_resultTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.Entity success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.Entity.class)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getEntity_result.class, metaDataMap);
    }

    public getEntity_result() {
    }

    public getEntity_result(
      org.apache.airavata.sharing.registry.models.Entity success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getEntity_result(getEntity_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.sharing.registry.models.Entity(other.success);
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getEntity_result deepCopy() {
      return new getEntity_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public org.apache.airavata.sharing.registry.models.Entity getSuccess() {
      return this.success;
    }

    public getEntity_result setSuccess(org.apache.airavata.sharing.registry.models.Entity success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getEntity_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.sharing.registry.models.Entity)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getEntity_result)
        return this.equals((getEntity_result)that);
      return false;
    }

    public boolean equals(getEntity_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getEntity_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getEntity_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.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, java.lang.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 getEntity_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntity_resultStandardScheme getScheme() {
        return new getEntity_resultStandardScheme();
      }
    }

    private static class getEntity_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getEntity_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getEntity_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.sharing.registry.models.Entity();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getEntity_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getEntity_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getEntity_resultTupleScheme getScheme() {
        return new getEntity_resultTupleScheme();
      }
    }

    private static class getEntity_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getEntity_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getEntity_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getEntity_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.sharing.registry.models.Entity();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class searchEntities_args implements org.apache.thrift.TBase<searchEntities_args, searchEntities_args._Fields>, java.io.Serializable, Cloneable, Comparable<searchEntities_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchEntities_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("userId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField FILTERS_FIELD_DESC = new org.apache.thrift.protocol.TField("filters", org.apache.thrift.protocol.TType.LIST, (short)3);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)4);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)5);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new searchEntities_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new searchEntities_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String userId; // required
    public java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters; // required
    public int offset; // required
    public int limit; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      USER_ID((short)2, "userId"),
      FILTERS((short)3, "filters"),
      OFFSET((short)4, "offset"),
      LIMIT((short)5, "limit");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // USER_ID
            return USER_ID;
          case 3: // FILTERS
            return FILTERS;
          case 4: // OFFSET
            return OFFSET;
          case 5: // LIMIT
            return LIMIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __OFFSET_ISSET_ID = 0;
    private static final int __LIMIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_ID, new org.apache.thrift.meta_data.FieldMetaData("userId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.FILTERS, new org.apache.thrift.meta_data.FieldMetaData("filters", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SearchCriteria.class))));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchEntities_args.class, metaDataMap);
    }

    public searchEntities_args() {
    }

    public searchEntities_args(
      java.lang.String domainId,
      java.lang.String userId,
      java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters,
      int offset,
      int limit)
    {
      this();
      this.domainId = domainId;
      this.userId = userId;
      this.filters = filters;
      this.offset = offset;
      setOffsetIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchEntities_args(searchEntities_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetUserId()) {
        this.userId = other.userId;
      }
      if (other.isSetFilters()) {
        java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> __this__filters = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.SearchCriteria>(other.filters.size());
        for (org.apache.airavata.sharing.registry.models.SearchCriteria other_element : other.filters) {
          __this__filters.add(new org.apache.airavata.sharing.registry.models.SearchCriteria(other_element));
        }
        this.filters = __this__filters;
      }
      this.offset = other.offset;
      this.limit = other.limit;
    }

    public searchEntities_args deepCopy() {
      return new searchEntities_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.userId = null;
      this.filters = null;
      setOffsetIsSet(false);
      this.offset = 0;
      setLimitIsSet(false);
      this.limit = 0;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public searchEntities_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getUserId() {
      return this.userId;
    }

    public searchEntities_args setUserId(java.lang.String userId) {
      this.userId = userId;
      return this;
    }

    public void unsetUserId() {
      this.userId = null;
    }

    /** Returns true if field userId is set (has been assigned a value) and false otherwise */
    public boolean isSetUserId() {
      return this.userId != null;
    }

    public void setUserIdIsSet(boolean value) {
      if (!value) {
        this.userId = null;
      }
    }

    public int getFiltersSize() {
      return (this.filters == null) ? 0 : this.filters.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.SearchCriteria> getFiltersIterator() {
      return (this.filters == null) ? null : this.filters.iterator();
    }

    public void addToFilters(org.apache.airavata.sharing.registry.models.SearchCriteria elem) {
      if (this.filters == null) {
        this.filters = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.SearchCriteria>();
      }
      this.filters.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> getFilters() {
      return this.filters;
    }

    public searchEntities_args setFilters(java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria> filters) {
      this.filters = filters;
      return this;
    }

    public void unsetFilters() {
      this.filters = null;
    }

    /** Returns true if field filters is set (has been assigned a value) and false otherwise */
    public boolean isSetFilters() {
      return this.filters != null;
    }

    public void setFiltersIsSet(boolean value) {
      if (!value) {
        this.filters = null;
      }
    }

    public int getOffset() {
      return this.offset;
    }

    public searchEntities_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public int getLimit() {
      return this.limit;
    }

    public searchEntities_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case USER_ID:
        if (value == null) {
          unsetUserId();
        } else {
          setUserId((java.lang.String)value);
        }
        break;

      case FILTERS:
        if (value == null) {
          unsetFilters();
        } else {
          setFilters((java.util.List<org.apache.airavata.sharing.registry.models.SearchCriteria>)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((java.lang.Integer)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case USER_ID:
        return getUserId();

      case FILTERS:
        return getFilters();

      case OFFSET:
        return getOffset();

      case LIMIT:
        return getLimit();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case USER_ID:
        return isSetUserId();
      case FILTERS:
        return isSetFilters();
      case OFFSET:
        return isSetOffset();
      case LIMIT:
        return isSetLimit();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof searchEntities_args)
        return this.equals((searchEntities_args)that);
      return false;
    }

    public boolean equals(searchEntities_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_userId = true && this.isSetUserId();
      boolean that_present_userId = true && that.isSetUserId();
      if (this_present_userId || that_present_userId) {
        if (!(this_present_userId && that_present_userId))
          return false;
        if (!this.userId.equals(that.userId))
          return false;
      }

      boolean this_present_filters = true && this.isSetFilters();
      boolean that_present_filters = true && that.isSetFilters();
      if (this_present_filters || that_present_filters) {
        if (!(this_present_filters && that_present_filters))
          return false;
        if (!this.filters.equals(that.filters))
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserId()) ? 131071 : 524287);
      if (isSetUserId())
        hashCode = hashCode * 8191 + userId.hashCode();

      hashCode = hashCode * 8191 + ((isSetFilters()) ? 131071 : 524287);
      if (isSetFilters())
        hashCode = hashCode * 8191 + filters.hashCode();

      hashCode = hashCode * 8191 + offset;

      hashCode = hashCode * 8191 + limit;

      return hashCode;
    }

    @Override
    public int compareTo(searchEntities_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserId()).compareTo(other.isSetUserId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userId, other.userId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetFilters()).compareTo(other.isSetFilters());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetFilters()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.filters, other.filters);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("searchEntities_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userId:");
      if (this.userId == null) {
        sb.append("null");
      } else {
        sb.append(this.userId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("filters:");
      if (this.filters == null) {
        sb.append("null");
      } else {
        sb.append(this.filters);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (userId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userId' was not present! Struct: " + toString());
      }
      if (filters == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'filters' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class searchEntities_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public searchEntities_argsStandardScheme getScheme() {
        return new searchEntities_argsStandardScheme();
      }
    }

    private static class searchEntities_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<searchEntities_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchEntities_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userId = iprot.readString();
                struct.setUserIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // FILTERS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list96 = iprot.readListBegin();
                  struct.filters = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.SearchCriteria>(_list96.size);
                  org.apache.airavata.sharing.registry.models.SearchCriteria _elem97;
                  for (int _i98 = 0; _i98 < _list96.size; ++_i98)
                  {
                    _elem97 = new org.apache.airavata.sharing.registry.models.SearchCriteria();
                    _elem97.read(iprot);
                    struct.filters.add(_elem97);
                  }
                  iprot.readListEnd();
                }
                struct.setFiltersIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchEntities_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.userId != null) {
          oprot.writeFieldBegin(USER_ID_FIELD_DESC);
          oprot.writeString(struct.userId);
          oprot.writeFieldEnd();
        }
        if (struct.filters != null) {
          oprot.writeFieldBegin(FILTERS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.filters.size()));
            for (org.apache.airavata.sharing.registry.models.SearchCriteria _iter99 : struct.filters)
            {
              _iter99.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchEntities_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public searchEntities_argsTupleScheme getScheme() {
        return new searchEntities_argsTupleScheme();
      }
    }

    private static class searchEntities_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<searchEntities_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchEntities_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.userId);
        {
          oprot.writeI32(struct.filters.size());
          for (org.apache.airavata.sharing.registry.models.SearchCriteria _iter100 : struct.filters)
          {
            _iter100.write(oprot);
          }
        }
        oprot.writeI32(struct.offset);
        oprot.writeI32(struct.limit);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchEntities_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.userId = iprot.readString();
        struct.setUserIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list101 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.filters = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.SearchCriteria>(_list101.size);
          org.apache.airavata.sharing.registry.models.SearchCriteria _elem102;
          for (int _i103 = 0; _i103 < _list101.size; ++_i103)
          {
            _elem102 = new org.apache.airavata.sharing.registry.models.SearchCriteria();
            _elem102.read(iprot);
            struct.filters.add(_elem102);
          }
        }
        struct.setFiltersIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class searchEntities_result implements org.apache.thrift.TBase<searchEntities_result, searchEntities_result._Fields>, java.io.Serializable, Cloneable, Comparable<searchEntities_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("searchEntities_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new searchEntities_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new searchEntities_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.Entity> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.Entity.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(searchEntities_result.class, metaDataMap);
    }

    public searchEntities_result() {
    }

    public searchEntities_result(
      java.util.List<org.apache.airavata.sharing.registry.models.Entity> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public searchEntities_result(searchEntities_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.Entity> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.Entity>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.Entity other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.Entity(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public searchEntities_result deepCopy() {
      return new searchEntities_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.Entity> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.Entity elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.Entity>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.Entity> getSuccess() {
      return this.success;
    }

    public searchEntities_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.Entity> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public searchEntities_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.Entity>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof searchEntities_result)
        return this.equals((searchEntities_result)that);
      return false;
    }

    public boolean equals(searchEntities_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(searchEntities_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("searchEntities_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 searchEntities_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public searchEntities_resultStandardScheme getScheme() {
        return new searchEntities_resultStandardScheme();
      }
    }

    private static class searchEntities_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<searchEntities_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, searchEntities_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list104 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.Entity>(_list104.size);
                  org.apache.airavata.sharing.registry.models.Entity _elem105;
                  for (int _i106 = 0; _i106 < _list104.size; ++_i106)
                  {
                    _elem105 = new org.apache.airavata.sharing.registry.models.Entity();
                    _elem105.read(iprot);
                    struct.success.add(_elem105);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, searchEntities_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.Entity _iter107 : struct.success)
            {
              _iter107.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class searchEntities_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public searchEntities_resultTupleScheme getScheme() {
        return new searchEntities_resultTupleScheme();
      }
    }

    private static class searchEntities_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<searchEntities_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, searchEntities_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.Entity _iter108 : struct.success)
            {
              _iter108.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, searchEntities_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list109 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.Entity>(_list109.size);
            org.apache.airavata.sharing.registry.models.Entity _elem110;
            for (int _i111 = 0; _i111 < _list109.size; ++_i111)
            {
              _elem110 = new org.apache.airavata.sharing.registry.models.Entity();
              _elem110.read(iprot);
              struct.success.add(_elem110);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getListOfSharedUsers_args implements org.apache.thrift.TBase<getListOfSharedUsers_args, getListOfSharedUsers_args._Fields>, java.io.Serializable, Cloneable, Comparable<getListOfSharedUsers_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getListOfSharedUsers_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getListOfSharedUsers_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getListOfSharedUsers_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId"),
      PERMISSION_TYPE_ID((short)3, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          case 3: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getListOfSharedUsers_args.class, metaDataMap);
    }

    public getListOfSharedUsers_args() {
    }

    public getListOfSharedUsers_args(
      java.lang.String domainId,
      java.lang.String entityId,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getListOfSharedUsers_args(getListOfSharedUsers_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public getListOfSharedUsers_args deepCopy() {
      return new getListOfSharedUsers_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getListOfSharedUsers_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public getListOfSharedUsers_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public getListOfSharedUsers_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getListOfSharedUsers_args)
        return this.equals((getListOfSharedUsers_args)that);
      return false;
    }

    public boolean equals(getListOfSharedUsers_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getListOfSharedUsers_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getListOfSharedUsers_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getListOfSharedUsers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfSharedUsers_argsStandardScheme getScheme() {
        return new getListOfSharedUsers_argsStandardScheme();
      }
    }

    private static class getListOfSharedUsers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getListOfSharedUsers_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getListOfSharedUsers_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getListOfSharedUsers_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getListOfSharedUsers_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfSharedUsers_argsTupleScheme getScheme() {
        return new getListOfSharedUsers_argsTupleScheme();
      }
    }

    private static class getListOfSharedUsers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getListOfSharedUsers_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getListOfSharedUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getListOfSharedUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getListOfSharedUsers_result implements org.apache.thrift.TBase<getListOfSharedUsers_result, getListOfSharedUsers_result._Fields>, java.io.Serializable, Cloneable, Comparable<getListOfSharedUsers_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getListOfSharedUsers_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getListOfSharedUsers_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getListOfSharedUsers_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.User> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.User.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getListOfSharedUsers_result.class, metaDataMap);
    }

    public getListOfSharedUsers_result() {
    }

    public getListOfSharedUsers_result(
      java.util.List<org.apache.airavata.sharing.registry.models.User> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getListOfSharedUsers_result(getListOfSharedUsers_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.User> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.User other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.User(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getListOfSharedUsers_result deepCopy() {
      return new getListOfSharedUsers_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.User> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.User elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> getSuccess() {
      return this.success;
    }

    public getListOfSharedUsers_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.User> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getListOfSharedUsers_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.User>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getListOfSharedUsers_result)
        return this.equals((getListOfSharedUsers_result)that);
      return false;
    }

    public boolean equals(getListOfSharedUsers_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getListOfSharedUsers_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getListOfSharedUsers_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getListOfSharedUsers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfSharedUsers_resultStandardScheme getScheme() {
        return new getListOfSharedUsers_resultStandardScheme();
      }
    }

    private static class getListOfSharedUsers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getListOfSharedUsers_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getListOfSharedUsers_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list112 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(_list112.size);
                  org.apache.airavata.sharing.registry.models.User _elem113;
                  for (int _i114 = 0; _i114 < _list112.size; ++_i114)
                  {
                    _elem113 = new org.apache.airavata.sharing.registry.models.User();
                    _elem113.read(iprot);
                    struct.success.add(_elem113);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getListOfSharedUsers_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.User _iter115 : struct.success)
            {
              _iter115.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getListOfSharedUsers_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfSharedUsers_resultTupleScheme getScheme() {
        return new getListOfSharedUsers_resultTupleScheme();
      }
    }

    private static class getListOfSharedUsers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getListOfSharedUsers_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getListOfSharedUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.User _iter116 : struct.success)
            {
              _iter116.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getListOfSharedUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list117 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(_list117.size);
            org.apache.airavata.sharing.registry.models.User _elem118;
            for (int _i119 = 0; _i119 < _list117.size; ++_i119)
            {
              _elem118 = new org.apache.airavata.sharing.registry.models.User();
              _elem118.read(iprot);
              struct.success.add(_elem118);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getListOfDirectlySharedUsers_args implements org.apache.thrift.TBase<getListOfDirectlySharedUsers_args, getListOfDirectlySharedUsers_args._Fields>, java.io.Serializable, Cloneable, Comparable<getListOfDirectlySharedUsers_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getListOfDirectlySharedUsers_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getListOfDirectlySharedUsers_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getListOfDirectlySharedUsers_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId"),
      PERMISSION_TYPE_ID((short)3, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          case 3: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getListOfDirectlySharedUsers_args.class, metaDataMap);
    }

    public getListOfDirectlySharedUsers_args() {
    }

    public getListOfDirectlySharedUsers_args(
      java.lang.String domainId,
      java.lang.String entityId,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getListOfDirectlySharedUsers_args(getListOfDirectlySharedUsers_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public getListOfDirectlySharedUsers_args deepCopy() {
      return new getListOfDirectlySharedUsers_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getListOfDirectlySharedUsers_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public getListOfDirectlySharedUsers_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public getListOfDirectlySharedUsers_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getListOfDirectlySharedUsers_args)
        return this.equals((getListOfDirectlySharedUsers_args)that);
      return false;
    }

    public boolean equals(getListOfDirectlySharedUsers_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getListOfDirectlySharedUsers_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getListOfDirectlySharedUsers_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getListOfDirectlySharedUsers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfDirectlySharedUsers_argsStandardScheme getScheme() {
        return new getListOfDirectlySharedUsers_argsStandardScheme();
      }
    }

    private static class getListOfDirectlySharedUsers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getListOfDirectlySharedUsers_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getListOfDirectlySharedUsers_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getListOfDirectlySharedUsers_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getListOfDirectlySharedUsers_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfDirectlySharedUsers_argsTupleScheme getScheme() {
        return new getListOfDirectlySharedUsers_argsTupleScheme();
      }
    }

    private static class getListOfDirectlySharedUsers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getListOfDirectlySharedUsers_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getListOfDirectlySharedUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getListOfDirectlySharedUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getListOfDirectlySharedUsers_result implements org.apache.thrift.TBase<getListOfDirectlySharedUsers_result, getListOfDirectlySharedUsers_result._Fields>, java.io.Serializable, Cloneable, Comparable<getListOfDirectlySharedUsers_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getListOfDirectlySharedUsers_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getListOfDirectlySharedUsers_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getListOfDirectlySharedUsers_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.User> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.User.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getListOfDirectlySharedUsers_result.class, metaDataMap);
    }

    public getListOfDirectlySharedUsers_result() {
    }

    public getListOfDirectlySharedUsers_result(
      java.util.List<org.apache.airavata.sharing.registry.models.User> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getListOfDirectlySharedUsers_result(getListOfDirectlySharedUsers_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.User> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.User other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.User(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getListOfDirectlySharedUsers_result deepCopy() {
      return new getListOfDirectlySharedUsers_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.User> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.User elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.User> getSuccess() {
      return this.success;
    }

    public getListOfDirectlySharedUsers_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.User> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getListOfDirectlySharedUsers_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.User>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getListOfDirectlySharedUsers_result)
        return this.equals((getListOfDirectlySharedUsers_result)that);
      return false;
    }

    public boolean equals(getListOfDirectlySharedUsers_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getListOfDirectlySharedUsers_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getListOfDirectlySharedUsers_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getListOfDirectlySharedUsers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfDirectlySharedUsers_resultStandardScheme getScheme() {
        return new getListOfDirectlySharedUsers_resultStandardScheme();
      }
    }

    private static class getListOfDirectlySharedUsers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getListOfDirectlySharedUsers_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getListOfDirectlySharedUsers_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list120 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(_list120.size);
                  org.apache.airavata.sharing.registry.models.User _elem121;
                  for (int _i122 = 0; _i122 < _list120.size; ++_i122)
                  {
                    _elem121 = new org.apache.airavata.sharing.registry.models.User();
                    _elem121.read(iprot);
                    struct.success.add(_elem121);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getListOfDirectlySharedUsers_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.User _iter123 : struct.success)
            {
              _iter123.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getListOfDirectlySharedUsers_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfDirectlySharedUsers_resultTupleScheme getScheme() {
        return new getListOfDirectlySharedUsers_resultTupleScheme();
      }
    }

    private static class getListOfDirectlySharedUsers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getListOfDirectlySharedUsers_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getListOfDirectlySharedUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.User _iter124 : struct.success)
            {
              _iter124.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getListOfDirectlySharedUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list125 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.User>(_list125.size);
            org.apache.airavata.sharing.registry.models.User _elem126;
            for (int _i127 = 0; _i127 < _list125.size; ++_i127)
            {
              _elem126 = new org.apache.airavata.sharing.registry.models.User();
              _elem126.read(iprot);
              struct.success.add(_elem126);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getListOfSharedGroups_args implements org.apache.thrift.TBase<getListOfSharedGroups_args, getListOfSharedGroups_args._Fields>, java.io.Serializable, Cloneable, Comparable<getListOfSharedGroups_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getListOfSharedGroups_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getListOfSharedGroups_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getListOfSharedGroups_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId"),
      PERMISSION_TYPE_ID((short)3, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          case 3: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getListOfSharedGroups_args.class, metaDataMap);
    }

    public getListOfSharedGroups_args() {
    }

    public getListOfSharedGroups_args(
      java.lang.String domainId,
      java.lang.String entityId,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getListOfSharedGroups_args(getListOfSharedGroups_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public getListOfSharedGroups_args deepCopy() {
      return new getListOfSharedGroups_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getListOfSharedGroups_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public getListOfSharedGroups_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public getListOfSharedGroups_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getListOfSharedGroups_args)
        return this.equals((getListOfSharedGroups_args)that);
      return false;
    }

    public boolean equals(getListOfSharedGroups_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getListOfSharedGroups_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getListOfSharedGroups_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getListOfSharedGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfSharedGroups_argsStandardScheme getScheme() {
        return new getListOfSharedGroups_argsStandardScheme();
      }
    }

    private static class getListOfSharedGroups_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getListOfSharedGroups_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getListOfSharedGroups_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getListOfSharedGroups_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getListOfSharedGroups_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfSharedGroups_argsTupleScheme getScheme() {
        return new getListOfSharedGroups_argsTupleScheme();
      }
    }

    private static class getListOfSharedGroups_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getListOfSharedGroups_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getListOfSharedGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getListOfSharedGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getListOfSharedGroups_result implements org.apache.thrift.TBase<getListOfSharedGroups_result, getListOfSharedGroups_result._Fields>, java.io.Serializable, Cloneable, Comparable<getListOfSharedGroups_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getListOfSharedGroups_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getListOfSharedGroups_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getListOfSharedGroups_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.UserGroup.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getListOfSharedGroups_result.class, metaDataMap);
    }

    public getListOfSharedGroups_result() {
    }

    public getListOfSharedGroups_result(
      java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getListOfSharedGroups_result(getListOfSharedGroups_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.UserGroup other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.UserGroup(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getListOfSharedGroups_result deepCopy() {
      return new getListOfSharedGroups_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.UserGroup> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.UserGroup elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getSuccess() {
      return this.success;
    }

    public getListOfSharedGroups_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getListOfSharedGroups_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getListOfSharedGroups_result)
        return this.equals((getListOfSharedGroups_result)that);
      return false;
    }

    public boolean equals(getListOfSharedGroups_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getListOfSharedGroups_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getListOfSharedGroups_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getListOfSharedGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfSharedGroups_resultStandardScheme getScheme() {
        return new getListOfSharedGroups_resultStandardScheme();
      }
    }

    private static class getListOfSharedGroups_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getListOfSharedGroups_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getListOfSharedGroups_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list128 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list128.size);
                  org.apache.airavata.sharing.registry.models.UserGroup _elem129;
                  for (int _i130 = 0; _i130 < _list128.size; ++_i130)
                  {
                    _elem129 = new org.apache.airavata.sharing.registry.models.UserGroup();
                    _elem129.read(iprot);
                    struct.success.add(_elem129);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getListOfSharedGroups_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter131 : struct.success)
            {
              _iter131.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getListOfSharedGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfSharedGroups_resultTupleScheme getScheme() {
        return new getListOfSharedGroups_resultTupleScheme();
      }
    }

    private static class getListOfSharedGroups_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getListOfSharedGroups_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getListOfSharedGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter132 : struct.success)
            {
              _iter132.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getListOfSharedGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list133 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list133.size);
            org.apache.airavata.sharing.registry.models.UserGroup _elem134;
            for (int _i135 = 0; _i135 < _list133.size; ++_i135)
            {
              _elem134 = new org.apache.airavata.sharing.registry.models.UserGroup();
              _elem134.read(iprot);
              struct.success.add(_elem134);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getListOfDirectlySharedGroups_args implements org.apache.thrift.TBase<getListOfDirectlySharedGroups_args, getListOfDirectlySharedGroups_args._Fields>, java.io.Serializable, Cloneable, Comparable<getListOfDirectlySharedGroups_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getListOfDirectlySharedGroups_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getListOfDirectlySharedGroups_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getListOfDirectlySharedGroups_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId"),
      PERMISSION_TYPE_ID((short)3, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          case 3: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getListOfDirectlySharedGroups_args.class, metaDataMap);
    }

    public getListOfDirectlySharedGroups_args() {
    }

    public getListOfDirectlySharedGroups_args(
      java.lang.String domainId,
      java.lang.String entityId,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getListOfDirectlySharedGroups_args(getListOfDirectlySharedGroups_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public getListOfDirectlySharedGroups_args deepCopy() {
      return new getListOfDirectlySharedGroups_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getListOfDirectlySharedGroups_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public getListOfDirectlySharedGroups_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public getListOfDirectlySharedGroups_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getListOfDirectlySharedGroups_args)
        return this.equals((getListOfDirectlySharedGroups_args)that);
      return false;
    }

    public boolean equals(getListOfDirectlySharedGroups_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getListOfDirectlySharedGroups_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getListOfDirectlySharedGroups_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getListOfDirectlySharedGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfDirectlySharedGroups_argsStandardScheme getScheme() {
        return new getListOfDirectlySharedGroups_argsStandardScheme();
      }
    }

    private static class getListOfDirectlySharedGroups_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getListOfDirectlySharedGroups_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getListOfDirectlySharedGroups_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getListOfDirectlySharedGroups_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getListOfDirectlySharedGroups_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfDirectlySharedGroups_argsTupleScheme getScheme() {
        return new getListOfDirectlySharedGroups_argsTupleScheme();
      }
    }

    private static class getListOfDirectlySharedGroups_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getListOfDirectlySharedGroups_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getListOfDirectlySharedGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getListOfDirectlySharedGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getListOfDirectlySharedGroups_result implements org.apache.thrift.TBase<getListOfDirectlySharedGroups_result, getListOfDirectlySharedGroups_result._Fields>, java.io.Serializable, Cloneable, Comparable<getListOfDirectlySharedGroups_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getListOfDirectlySharedGroups_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getListOfDirectlySharedGroups_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getListOfDirectlySharedGroups_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.UserGroup.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getListOfDirectlySharedGroups_result.class, metaDataMap);
    }

    public getListOfDirectlySharedGroups_result() {
    }

    public getListOfDirectlySharedGroups_result(
      java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getListOfDirectlySharedGroups_result(getListOfDirectlySharedGroups_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.UserGroup other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.UserGroup(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getListOfDirectlySharedGroups_result deepCopy() {
      return new getListOfDirectlySharedGroups_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.UserGroup> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.UserGroup elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> getSuccess() {
      return this.success;
    }

    public getListOfDirectlySharedGroups_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.UserGroup> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getListOfDirectlySharedGroups_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.UserGroup>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getListOfDirectlySharedGroups_result)
        return this.equals((getListOfDirectlySharedGroups_result)that);
      return false;
    }

    public boolean equals(getListOfDirectlySharedGroups_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getListOfDirectlySharedGroups_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getListOfDirectlySharedGroups_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getListOfDirectlySharedGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfDirectlySharedGroups_resultStandardScheme getScheme() {
        return new getListOfDirectlySharedGroups_resultStandardScheme();
      }
    }

    private static class getListOfDirectlySharedGroups_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getListOfDirectlySharedGroups_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getListOfDirectlySharedGroups_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list136 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list136.size);
                  org.apache.airavata.sharing.registry.models.UserGroup _elem137;
                  for (int _i138 = 0; _i138 < _list136.size; ++_i138)
                  {
                    _elem137 = new org.apache.airavata.sharing.registry.models.UserGroup();
                    _elem137.read(iprot);
                    struct.success.add(_elem137);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getListOfDirectlySharedGroups_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter139 : struct.success)
            {
              _iter139.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getListOfDirectlySharedGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getListOfDirectlySharedGroups_resultTupleScheme getScheme() {
        return new getListOfDirectlySharedGroups_resultTupleScheme();
      }
    }

    private static class getListOfDirectlySharedGroups_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getListOfDirectlySharedGroups_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getListOfDirectlySharedGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.UserGroup _iter140 : struct.success)
            {
              _iter140.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getListOfDirectlySharedGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list141 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.UserGroup>(_list141.size);
            org.apache.airavata.sharing.registry.models.UserGroup _elem142;
            for (int _i143 = 0; _i143 < _list141.size; ++_i143)
            {
              _elem142 = new org.apache.airavata.sharing.registry.models.UserGroup();
              _elem142.read(iprot);
              struct.success.add(_elem142);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class createPermissionType_args implements org.apache.thrift.TBase<createPermissionType_args, createPermissionType_args._Fields>, java.io.Serializable, Cloneable, Comparable<createPermissionType_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createPermissionType_args");

    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionType", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createPermissionType_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createPermissionType_argsTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.PermissionType permissionType; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      PERMISSION_TYPE((short)1, "permissionType");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // PERMISSION_TYPE
            return PERMISSION_TYPE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.PERMISSION_TYPE, new org.apache.thrift.meta_data.FieldMetaData("permissionType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.PermissionType.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createPermissionType_args.class, metaDataMap);
    }

    public createPermissionType_args() {
    }

    public createPermissionType_args(
      org.apache.airavata.sharing.registry.models.PermissionType permissionType)
    {
      this();
      this.permissionType = permissionType;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createPermissionType_args(createPermissionType_args other) {
      if (other.isSetPermissionType()) {
        this.permissionType = new org.apache.airavata.sharing.registry.models.PermissionType(other.permissionType);
      }
    }

    public createPermissionType_args deepCopy() {
      return new createPermissionType_args(this);
    }

    @Override
    public void clear() {
      this.permissionType = null;
    }

    public org.apache.airavata.sharing.registry.models.PermissionType getPermissionType() {
      return this.permissionType;
    }

    public createPermissionType_args setPermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType) {
      this.permissionType = permissionType;
      return this;
    }

    public void unsetPermissionType() {
      this.permissionType = null;
    }

    /** Returns true if field permissionType is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionType() {
      return this.permissionType != null;
    }

    public void setPermissionTypeIsSet(boolean value) {
      if (!value) {
        this.permissionType = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case PERMISSION_TYPE:
        if (value == null) {
          unsetPermissionType();
        } else {
          setPermissionType((org.apache.airavata.sharing.registry.models.PermissionType)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case PERMISSION_TYPE:
        return getPermissionType();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case PERMISSION_TYPE:
        return isSetPermissionType();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createPermissionType_args)
        return this.equals((createPermissionType_args)that);
      return false;
    }

    public boolean equals(createPermissionType_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_permissionType = true && this.isSetPermissionType();
      boolean that_present_permissionType = true && that.isSetPermissionType();
      if (this_present_permissionType || that_present_permissionType) {
        if (!(this_present_permissionType && that_present_permissionType))
          return false;
        if (!this.permissionType.equals(that.permissionType))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetPermissionType()) ? 131071 : 524287);
      if (isSetPermissionType())
        hashCode = hashCode * 8191 + permissionType.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createPermissionType_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetPermissionType()).compareTo(other.isSetPermissionType());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionType()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionType, other.permissionType);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createPermissionType_args(");
      boolean first = true;

      sb.append("permissionType:");
      if (this.permissionType == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionType);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (permissionType == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionType' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (permissionType != null) {
        permissionType.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, java.lang.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 createPermissionType_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createPermissionType_argsStandardScheme getScheme() {
        return new createPermissionType_argsStandardScheme();
      }
    }

    private static class createPermissionType_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<createPermissionType_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createPermissionType_args 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: // PERMISSION_TYPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.permissionType = new org.apache.airavata.sharing.registry.models.PermissionType();
                struct.permissionType.read(iprot);
                struct.setPermissionTypeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createPermissionType_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.permissionType != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_FIELD_DESC);
          struct.permissionType.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createPermissionType_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createPermissionType_argsTupleScheme getScheme() {
        return new createPermissionType_argsTupleScheme();
      }
    }

    private static class createPermissionType_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<createPermissionType_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createPermissionType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.permissionType.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createPermissionType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.permissionType = new org.apache.airavata.sharing.registry.models.PermissionType();
        struct.permissionType.read(iprot);
        struct.setPermissionTypeIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class createPermissionType_result implements org.apache.thrift.TBase<createPermissionType_result, createPermissionType_result._Fields>, java.io.Serializable, Cloneable, Comparable<createPermissionType_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("createPermissionType_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRING, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);
    private static final org.apache.thrift.protocol.TField DEE_FIELD_DESC = new org.apache.thrift.protocol.TField("dee", org.apache.thrift.protocol.TType.STRUCT, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new createPermissionType_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new createPermissionType_resultTupleSchemeFactory();

    public java.lang.String success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required
    public org.apache.airavata.sharing.registry.models.DuplicateEntryException dee; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre"),
      DEE((short)2, "dee");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          case 2: // DEE
            return DEE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      tmpMap.put(_Fields.DEE, new org.apache.thrift.meta_data.FieldMetaData("dee", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.DuplicateEntryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(createPermissionType_result.class, metaDataMap);
    }

    public createPermissionType_result() {
    }

    public createPermissionType_result(
      java.lang.String success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre,
      org.apache.airavata.sharing.registry.models.DuplicateEntryException dee)
    {
      this();
      this.success = success;
      this.sre = sre;
      this.dee = dee;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public createPermissionType_result(createPermissionType_result other) {
      if (other.isSetSuccess()) {
        this.success = other.success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
      if (other.isSetDee()) {
        this.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException(other.dee);
      }
    }

    public createPermissionType_result deepCopy() {
      return new createPermissionType_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
      this.dee = null;
    }

    public java.lang.String getSuccess() {
      return this.success;
    }

    public createPermissionType_result setSuccess(java.lang.String success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public createPermissionType_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.DuplicateEntryException getDee() {
      return this.dee;
    }

    public createPermissionType_result setDee(org.apache.airavata.sharing.registry.models.DuplicateEntryException dee) {
      this.dee = dee;
      return this;
    }

    public void unsetDee() {
      this.dee = null;
    }

    /** Returns true if field dee is set (has been assigned a value) and false otherwise */
    public boolean isSetDee() {
      return this.dee != null;
    }

    public void setDeeIsSet(boolean value) {
      if (!value) {
        this.dee = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.String)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      case DEE:
        if (value == null) {
          unsetDee();
        } else {
          setDee((org.apache.airavata.sharing.registry.models.DuplicateEntryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      case DEE:
        return getDee();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      case DEE:
        return isSetDee();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof createPermissionType_result)
        return this.equals((createPermissionType_result)that);
      return false;
    }

    public boolean equals(createPermissionType_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      boolean this_present_dee = true && this.isSetDee();
      boolean that_present_dee = true && that.isSetDee();
      if (this_present_dee || that_present_dee) {
        if (!(this_present_dee && that_present_dee))
          return false;
        if (!this.dee.equals(that.dee))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      hashCode = hashCode * 8191 + ((isSetDee()) ? 131071 : 524287);
      if (isSetDee())
        hashCode = hashCode * 8191 + dee.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(createPermissionType_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetDee()).compareTo(other.isSetDee());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDee()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dee, other.dee);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("createPermissionType_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("dee:");
      if (this.dee == null) {
        sb.append("null");
      } else {
        sb.append(this.dee);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 createPermissionType_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createPermissionType_resultStandardScheme getScheme() {
        return new createPermissionType_resultStandardScheme();
      }
    }

    private static class createPermissionType_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<createPermissionType_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, createPermissionType_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.success = iprot.readString();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // DEE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException();
                struct.dee.read(iprot);
                struct.setDeeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, createPermissionType_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeString(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.dee != null) {
          oprot.writeFieldBegin(DEE_FIELD_DESC);
          struct.dee.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class createPermissionType_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public createPermissionType_resultTupleScheme getScheme() {
        return new createPermissionType_resultTupleScheme();
      }
    }

    private static class createPermissionType_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<createPermissionType_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, createPermissionType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        if (struct.isSetDee()) {
          optionals.set(2);
        }
        oprot.writeBitSet(optionals, 3);
        if (struct.isSetSuccess()) {
          oprot.writeString(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
        if (struct.isSetDee()) {
          struct.dee.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, createPermissionType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(3);
        if (incoming.get(0)) {
          struct.success = iprot.readString();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
        if (incoming.get(2)) {
          struct.dee = new org.apache.airavata.sharing.registry.models.DuplicateEntryException();
          struct.dee.read(iprot);
          struct.setDeeIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class updatePermissionType_args implements org.apache.thrift.TBase<updatePermissionType_args, updatePermissionType_args._Fields>, java.io.Serializable, Cloneable, Comparable<updatePermissionType_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updatePermissionType_args");

    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionType", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updatePermissionType_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updatePermissionType_argsTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.PermissionType permissionType; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      PERMISSION_TYPE((short)1, "permissionType");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // PERMISSION_TYPE
            return PERMISSION_TYPE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.PERMISSION_TYPE, new org.apache.thrift.meta_data.FieldMetaData("permissionType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.PermissionType.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updatePermissionType_args.class, metaDataMap);
    }

    public updatePermissionType_args() {
    }

    public updatePermissionType_args(
      org.apache.airavata.sharing.registry.models.PermissionType permissionType)
    {
      this();
      this.permissionType = permissionType;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updatePermissionType_args(updatePermissionType_args other) {
      if (other.isSetPermissionType()) {
        this.permissionType = new org.apache.airavata.sharing.registry.models.PermissionType(other.permissionType);
      }
    }

    public updatePermissionType_args deepCopy() {
      return new updatePermissionType_args(this);
    }

    @Override
    public void clear() {
      this.permissionType = null;
    }

    public org.apache.airavata.sharing.registry.models.PermissionType getPermissionType() {
      return this.permissionType;
    }

    public updatePermissionType_args setPermissionType(org.apache.airavata.sharing.registry.models.PermissionType permissionType) {
      this.permissionType = permissionType;
      return this;
    }

    public void unsetPermissionType() {
      this.permissionType = null;
    }

    /** Returns true if field permissionType is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionType() {
      return this.permissionType != null;
    }

    public void setPermissionTypeIsSet(boolean value) {
      if (!value) {
        this.permissionType = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case PERMISSION_TYPE:
        if (value == null) {
          unsetPermissionType();
        } else {
          setPermissionType((org.apache.airavata.sharing.registry.models.PermissionType)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case PERMISSION_TYPE:
        return getPermissionType();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case PERMISSION_TYPE:
        return isSetPermissionType();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updatePermissionType_args)
        return this.equals((updatePermissionType_args)that);
      return false;
    }

    public boolean equals(updatePermissionType_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_permissionType = true && this.isSetPermissionType();
      boolean that_present_permissionType = true && that.isSetPermissionType();
      if (this_present_permissionType || that_present_permissionType) {
        if (!(this_present_permissionType && that_present_permissionType))
          return false;
        if (!this.permissionType.equals(that.permissionType))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetPermissionType()) ? 131071 : 524287);
      if (isSetPermissionType())
        hashCode = hashCode * 8191 + permissionType.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updatePermissionType_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetPermissionType()).compareTo(other.isSetPermissionType());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionType()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionType, other.permissionType);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updatePermissionType_args(");
      boolean first = true;

      sb.append("permissionType:");
      if (this.permissionType == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionType);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (permissionType == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionType' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
      if (permissionType != null) {
        permissionType.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, java.lang.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 updatePermissionType_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updatePermissionType_argsStandardScheme getScheme() {
        return new updatePermissionType_argsStandardScheme();
      }
    }

    private static class updatePermissionType_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<updatePermissionType_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updatePermissionType_args 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: // PERMISSION_TYPE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.permissionType = new org.apache.airavata.sharing.registry.models.PermissionType();
                struct.permissionType.read(iprot);
                struct.setPermissionTypeIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updatePermissionType_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.permissionType != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_FIELD_DESC);
          struct.permissionType.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updatePermissionType_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updatePermissionType_argsTupleScheme getScheme() {
        return new updatePermissionType_argsTupleScheme();
      }
    }

    private static class updatePermissionType_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<updatePermissionType_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updatePermissionType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.permissionType.write(oprot);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updatePermissionType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.permissionType = new org.apache.airavata.sharing.registry.models.PermissionType();
        struct.permissionType.read(iprot);
        struct.setPermissionTypeIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class updatePermissionType_result implements org.apache.thrift.TBase<updatePermissionType_result, updatePermissionType_result._Fields>, java.io.Serializable, Cloneable, Comparable<updatePermissionType_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("updatePermissionType_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new updatePermissionType_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new updatePermissionType_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(updatePermissionType_result.class, metaDataMap);
    }

    public updatePermissionType_result() {
    }

    public updatePermissionType_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public updatePermissionType_result(updatePermissionType_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public updatePermissionType_result deepCopy() {
      return new updatePermissionType_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public updatePermissionType_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public updatePermissionType_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof updatePermissionType_result)
        return this.equals((updatePermissionType_result)that);
      return false;
    }

    public boolean equals(updatePermissionType_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(updatePermissionType_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("updatePermissionType_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class updatePermissionType_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updatePermissionType_resultStandardScheme getScheme() {
        return new updatePermissionType_resultStandardScheme();
      }
    }

    private static class updatePermissionType_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<updatePermissionType_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, updatePermissionType_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, updatePermissionType_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class updatePermissionType_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public updatePermissionType_resultTupleScheme getScheme() {
        return new updatePermissionType_resultTupleScheme();
      }
    }

    private static class updatePermissionType_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<updatePermissionType_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, updatePermissionType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, updatePermissionType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isPermissionExists_args implements org.apache.thrift.TBase<isPermissionExists_args, isPermissionExists_args._Fields>, java.io.Serializable, Cloneable, Comparable<isPermissionExists_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isPermissionExists_args");

    private static final org.apache.thrift.protocol.TField DIMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("dimainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField PERMISSION_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isPermissionExists_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isPermissionExists_argsTupleSchemeFactory();

    public java.lang.String dimainId; // required
    public java.lang.String permissionId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DIMAIN_ID((short)1, "dimainId"),
      PERMISSION_ID((short)2, "permissionId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DIMAIN_ID
            return DIMAIN_ID;
          case 2: // PERMISSION_ID
            return PERMISSION_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DIMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("dimainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERMISSION_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isPermissionExists_args.class, metaDataMap);
    }

    public isPermissionExists_args() {
    }

    public isPermissionExists_args(
      java.lang.String dimainId,
      java.lang.String permissionId)
    {
      this();
      this.dimainId = dimainId;
      this.permissionId = permissionId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isPermissionExists_args(isPermissionExists_args other) {
      if (other.isSetDimainId()) {
        this.dimainId = other.dimainId;
      }
      if (other.isSetPermissionId()) {
        this.permissionId = other.permissionId;
      }
    }

    public isPermissionExists_args deepCopy() {
      return new isPermissionExists_args(this);
    }

    @Override
    public void clear() {
      this.dimainId = null;
      this.permissionId = null;
    }

    public java.lang.String getDimainId() {
      return this.dimainId;
    }

    public isPermissionExists_args setDimainId(java.lang.String dimainId) {
      this.dimainId = dimainId;
      return this;
    }

    public void unsetDimainId() {
      this.dimainId = null;
    }

    /** Returns true if field dimainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDimainId() {
      return this.dimainId != null;
    }

    public void setDimainIdIsSet(boolean value) {
      if (!value) {
        this.dimainId = null;
      }
    }

    public java.lang.String getPermissionId() {
      return this.permissionId;
    }

    public isPermissionExists_args setPermissionId(java.lang.String permissionId) {
      this.permissionId = permissionId;
      return this;
    }

    public void unsetPermissionId() {
      this.permissionId = null;
    }

    /** Returns true if field permissionId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionId() {
      return this.permissionId != null;
    }

    public void setPermissionIdIsSet(boolean value) {
      if (!value) {
        this.permissionId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DIMAIN_ID:
        if (value == null) {
          unsetDimainId();
        } else {
          setDimainId((java.lang.String)value);
        }
        break;

      case PERMISSION_ID:
        if (value == null) {
          unsetPermissionId();
        } else {
          setPermissionId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DIMAIN_ID:
        return getDimainId();

      case PERMISSION_ID:
        return getPermissionId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DIMAIN_ID:
        return isSetDimainId();
      case PERMISSION_ID:
        return isSetPermissionId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isPermissionExists_args)
        return this.equals((isPermissionExists_args)that);
      return false;
    }

    public boolean equals(isPermissionExists_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_dimainId = true && this.isSetDimainId();
      boolean that_present_dimainId = true && that.isSetDimainId();
      if (this_present_dimainId || that_present_dimainId) {
        if (!(this_present_dimainId && that_present_dimainId))
          return false;
        if (!this.dimainId.equals(that.dimainId))
          return false;
      }

      boolean this_present_permissionId = true && this.isSetPermissionId();
      boolean that_present_permissionId = true && that.isSetPermissionId();
      if (this_present_permissionId || that_present_permissionId) {
        if (!(this_present_permissionId && that_present_permissionId))
          return false;
        if (!this.permissionId.equals(that.permissionId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDimainId()) ? 131071 : 524287);
      if (isSetDimainId())
        hashCode = hashCode * 8191 + dimainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionId()) ? 131071 : 524287);
      if (isSetPermissionId())
        hashCode = hashCode * 8191 + permissionId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isPermissionExists_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDimainId()).compareTo(other.isSetDimainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDimainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.dimainId, other.dimainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionId()).compareTo(other.isSetPermissionId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionId, other.permissionId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isPermissionExists_args(");
      boolean first = true;

      sb.append("dimainId:");
      if (this.dimainId == null) {
        sb.append("null");
      } else {
        sb.append(this.dimainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionId:");
      if (this.permissionId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (dimainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'dimainId' was not present! Struct: " + toString());
      }
      if (permissionId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 isPermissionExists_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isPermissionExists_argsStandardScheme getScheme() {
        return new isPermissionExists_argsStandardScheme();
      }
    }

    private static class isPermissionExists_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<isPermissionExists_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isPermissionExists_args 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: // DIMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.dimainId = iprot.readString();
                struct.setDimainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PERMISSION_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionId = iprot.readString();
                struct.setPermissionIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isPermissionExists_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.dimainId != null) {
          oprot.writeFieldBegin(DIMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.dimainId);
          oprot.writeFieldEnd();
        }
        if (struct.permissionId != null) {
          oprot.writeFieldBegin(PERMISSION_ID_FIELD_DESC);
          oprot.writeString(struct.permissionId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isPermissionExists_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isPermissionExists_argsTupleScheme getScheme() {
        return new isPermissionExists_argsTupleScheme();
      }
    }

    private static class isPermissionExists_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<isPermissionExists_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isPermissionExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.dimainId);
        oprot.writeString(struct.permissionId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isPermissionExists_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.dimainId = iprot.readString();
        struct.setDimainIdIsSet(true);
        struct.permissionId = iprot.readString();
        struct.setPermissionIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class isPermissionExists_result implements org.apache.thrift.TBase<isPermissionExists_result, isPermissionExists_result._Fields>, java.io.Serializable, Cloneable, Comparable<isPermissionExists_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("isPermissionExists_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new isPermissionExists_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new isPermissionExists_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(isPermissionExists_result.class, metaDataMap);
    }

    public isPermissionExists_result() {
    }

    public isPermissionExists_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public isPermissionExists_result(isPermissionExists_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public isPermissionExists_result deepCopy() {
      return new isPermissionExists_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public isPermissionExists_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public isPermissionExists_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof isPermissionExists_result)
        return this.equals((isPermissionExists_result)that);
      return false;
    }

    public boolean equals(isPermissionExists_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(isPermissionExists_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("isPermissionExists_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class isPermissionExists_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isPermissionExists_resultStandardScheme getScheme() {
        return new isPermissionExists_resultStandardScheme();
      }
    }

    private static class isPermissionExists_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<isPermissionExists_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, isPermissionExists_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, isPermissionExists_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class isPermissionExists_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public isPermissionExists_resultTupleScheme getScheme() {
        return new isPermissionExists_resultTupleScheme();
      }
    }

    private static class isPermissionExists_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<isPermissionExists_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, isPermissionExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, isPermissionExists_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deletePermissionType_args implements org.apache.thrift.TBase<deletePermissionType_args, deletePermissionType_args._Fields>, java.io.Serializable, Cloneable, Comparable<deletePermissionType_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deletePermissionType_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deletePermissionType_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deletePermissionType_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      PERMISSION_TYPE_ID((short)2, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deletePermissionType_args.class, metaDataMap);
    }

    public deletePermissionType_args() {
    }

    public deletePermissionType_args(
      java.lang.String domainId,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deletePermissionType_args(deletePermissionType_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public deletePermissionType_args deepCopy() {
      return new deletePermissionType_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public deletePermissionType_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public deletePermissionType_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deletePermissionType_args)
        return this.equals((deletePermissionType_args)that);
      return false;
    }

    public boolean equals(deletePermissionType_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deletePermissionType_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deletePermissionType_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 deletePermissionType_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deletePermissionType_argsStandardScheme getScheme() {
        return new deletePermissionType_argsStandardScheme();
      }
    }

    private static class deletePermissionType_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<deletePermissionType_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deletePermissionType_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deletePermissionType_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deletePermissionType_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deletePermissionType_argsTupleScheme getScheme() {
        return new deletePermissionType_argsTupleScheme();
      }
    }

    private static class deletePermissionType_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<deletePermissionType_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deletePermissionType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deletePermissionType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class deletePermissionType_result implements org.apache.thrift.TBase<deletePermissionType_result, deletePermissionType_result._Fields>, java.io.Serializable, Cloneable, Comparable<deletePermissionType_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("deletePermissionType_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new deletePermissionType_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new deletePermissionType_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(deletePermissionType_result.class, metaDataMap);
    }

    public deletePermissionType_result() {
    }

    public deletePermissionType_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public deletePermissionType_result(deletePermissionType_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public deletePermissionType_result deepCopy() {
      return new deletePermissionType_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public deletePermissionType_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public deletePermissionType_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof deletePermissionType_result)
        return this.equals((deletePermissionType_result)that);
      return false;
    }

    public boolean equals(deletePermissionType_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(deletePermissionType_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("deletePermissionType_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class deletePermissionType_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deletePermissionType_resultStandardScheme getScheme() {
        return new deletePermissionType_resultStandardScheme();
      }
    }

    private static class deletePermissionType_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<deletePermissionType_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, deletePermissionType_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, deletePermissionType_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class deletePermissionType_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public deletePermissionType_resultTupleScheme getScheme() {
        return new deletePermissionType_resultTupleScheme();
      }
    }

    private static class deletePermissionType_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<deletePermissionType_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, deletePermissionType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, deletePermissionType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getPermissionType_args implements org.apache.thrift.TBase<getPermissionType_args, getPermissionType_args._Fields>, java.io.Serializable, Cloneable, Comparable<getPermissionType_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getPermissionType_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)2);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getPermissionType_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getPermissionType_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      PERMISSION_TYPE_ID((short)2, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getPermissionType_args.class, metaDataMap);
    }

    public getPermissionType_args() {
    }

    public getPermissionType_args(
      java.lang.String domainId,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getPermissionType_args(getPermissionType_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public getPermissionType_args deepCopy() {
      return new getPermissionType_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getPermissionType_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public getPermissionType_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getPermissionType_args)
        return this.equals((getPermissionType_args)that);
      return false;
    }

    public boolean equals(getPermissionType_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getPermissionType_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getPermissionType_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 getPermissionType_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getPermissionType_argsStandardScheme getScheme() {
        return new getPermissionType_argsStandardScheme();
      }
    }

    private static class getPermissionType_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getPermissionType_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getPermissionType_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getPermissionType_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getPermissionType_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getPermissionType_argsTupleScheme getScheme() {
        return new getPermissionType_argsTupleScheme();
      }
    }

    private static class getPermissionType_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getPermissionType_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getPermissionType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getPermissionType_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getPermissionType_result implements org.apache.thrift.TBase<getPermissionType_result, getPermissionType_result._Fields>, java.io.Serializable, Cloneable, Comparable<getPermissionType_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getPermissionType_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getPermissionType_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getPermissionType_resultTupleSchemeFactory();

    public org.apache.airavata.sharing.registry.models.PermissionType success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.PermissionType.class)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getPermissionType_result.class, metaDataMap);
    }

    public getPermissionType_result() {
    }

    public getPermissionType_result(
      org.apache.airavata.sharing.registry.models.PermissionType success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getPermissionType_result(getPermissionType_result other) {
      if (other.isSetSuccess()) {
        this.success = new org.apache.airavata.sharing.registry.models.PermissionType(other.success);
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getPermissionType_result deepCopy() {
      return new getPermissionType_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public org.apache.airavata.sharing.registry.models.PermissionType getSuccess() {
      return this.success;
    }

    public getPermissionType_result setSuccess(org.apache.airavata.sharing.registry.models.PermissionType success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getPermissionType_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((org.apache.airavata.sharing.registry.models.PermissionType)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getPermissionType_result)
        return this.equals((getPermissionType_result)that);
      return false;
    }

    public boolean equals(getPermissionType_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getPermissionType_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getPermissionType_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
      if (success != null) {
        success.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, java.lang.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 getPermissionType_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getPermissionType_resultStandardScheme getScheme() {
        return new getPermissionType_resultStandardScheme();
      }
    }

    private static class getPermissionType_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getPermissionType_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getPermissionType_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.success = new org.apache.airavata.sharing.registry.models.PermissionType();
                struct.success.read(iprot);
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getPermissionType_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          struct.success.write(oprot);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getPermissionType_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getPermissionType_resultTupleScheme getScheme() {
        return new getPermissionType_resultTupleScheme();
      }
    }

    private static class getPermissionType_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getPermissionType_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getPermissionType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          struct.success.write(oprot);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getPermissionType_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = new org.apache.airavata.sharing.registry.models.PermissionType();
          struct.success.read(iprot);
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getPermissionTypes_args implements org.apache.thrift.TBase<getPermissionTypes_args, getPermissionTypes_args._Fields>, java.io.Serializable, Cloneable, Comparable<getPermissionTypes_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getPermissionTypes_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("offset", org.apache.thrift.protocol.TType.I32, (short)2);
    private static final org.apache.thrift.protocol.TField LIMIT_FIELD_DESC = new org.apache.thrift.protocol.TField("limit", org.apache.thrift.protocol.TType.I32, (short)3);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getPermissionTypes_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getPermissionTypes_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public int offset; // required
    public int limit; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      OFFSET((short)2, "offset"),
      LIMIT((short)3, "limit");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // OFFSET
            return OFFSET;
          case 3: // LIMIT
            return LIMIT;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __OFFSET_ISSET_ID = 0;
    private static final int __LIMIT_ISSET_ID = 1;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.OFFSET, new org.apache.thrift.meta_data.FieldMetaData("offset", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      tmpMap.put(_Fields.LIMIT, new org.apache.thrift.meta_data.FieldMetaData("limit", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getPermissionTypes_args.class, metaDataMap);
    }

    public getPermissionTypes_args() {
    }

    public getPermissionTypes_args(
      java.lang.String domainId,
      int offset,
      int limit)
    {
      this();
      this.domainId = domainId;
      this.offset = offset;
      setOffsetIsSet(true);
      this.limit = limit;
      setLimitIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getPermissionTypes_args(getPermissionTypes_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      this.offset = other.offset;
      this.limit = other.limit;
    }

    public getPermissionTypes_args deepCopy() {
      return new getPermissionTypes_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      setOffsetIsSet(false);
      this.offset = 0;
      setLimitIsSet(false);
      this.limit = 0;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public getPermissionTypes_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public int getOffset() {
      return this.offset;
    }

    public getPermissionTypes_args setOffset(int offset) {
      this.offset = offset;
      setOffsetIsSet(true);
      return this;
    }

    public void unsetOffset() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    /** Returns true if field offset is set (has been assigned a value) and false otherwise */
    public boolean isSetOffset() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __OFFSET_ISSET_ID);
    }

    public void setOffsetIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __OFFSET_ISSET_ID, value);
    }

    public int getLimit() {
      return this.limit;
    }

    public getPermissionTypes_args setLimit(int limit) {
      this.limit = limit;
      setLimitIsSet(true);
      return this;
    }

    public void unsetLimit() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    /** Returns true if field limit is set (has been assigned a value) and false otherwise */
    public boolean isSetLimit() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __LIMIT_ISSET_ID);
    }

    public void setLimitIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __LIMIT_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case OFFSET:
        if (value == null) {
          unsetOffset();
        } else {
          setOffset((java.lang.Integer)value);
        }
        break;

      case LIMIT:
        if (value == null) {
          unsetLimit();
        } else {
          setLimit((java.lang.Integer)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case OFFSET:
        return getOffset();

      case LIMIT:
        return getLimit();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case OFFSET:
        return isSetOffset();
      case LIMIT:
        return isSetLimit();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getPermissionTypes_args)
        return this.equals((getPermissionTypes_args)that);
      return false;
    }

    public boolean equals(getPermissionTypes_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_offset = true;
      boolean that_present_offset = true;
      if (this_present_offset || that_present_offset) {
        if (!(this_present_offset && that_present_offset))
          return false;
        if (this.offset != that.offset)
          return false;
      }

      boolean this_present_limit = true;
      boolean that_present_limit = true;
      if (this_present_limit || that_present_limit) {
        if (!(this_present_limit && that_present_limit))
          return false;
        if (this.limit != that.limit)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + offset;

      hashCode = hashCode * 8191 + limit;

      return hashCode;
    }

    @Override
    public int compareTo(getPermissionTypes_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetOffset()).compareTo(other.isSetOffset());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetOffset()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.offset, other.offset);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetLimit()).compareTo(other.isSetLimit());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetLimit()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.limit, other.limit);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getPermissionTypes_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("offset:");
      sb.append(this.offset);
      first = false;
      if (!first) sb.append(", ");
      sb.append("limit:");
      sb.append(this.limit);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'offset' because it's a primitive and you chose the non-beans generator.
      // alas, we cannot check 'limit' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class getPermissionTypes_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getPermissionTypes_argsStandardScheme getScheme() {
        return new getPermissionTypes_argsStandardScheme();
      }
    }

    private static class getPermissionTypes_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<getPermissionTypes_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getPermissionTypes_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // OFFSET
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.offset = iprot.readI32();
                struct.setOffsetIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // LIMIT
              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                struct.limit = iprot.readI32();
                struct.setLimitIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetOffset()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'offset' was not found in serialized data! Struct: " + toString());
        }
        if (!struct.isSetLimit()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'limit' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getPermissionTypes_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(OFFSET_FIELD_DESC);
        oprot.writeI32(struct.offset);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(LIMIT_FIELD_DESC);
        oprot.writeI32(struct.limit);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getPermissionTypes_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getPermissionTypes_argsTupleScheme getScheme() {
        return new getPermissionTypes_argsTupleScheme();
      }
    }

    private static class getPermissionTypes_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<getPermissionTypes_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getPermissionTypes_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeI32(struct.offset);
        oprot.writeI32(struct.limit);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getPermissionTypes_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.offset = iprot.readI32();
        struct.setOffsetIsSet(true);
        struct.limit = iprot.readI32();
        struct.setLimitIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class getPermissionTypes_result implements org.apache.thrift.TBase<getPermissionTypes_result, getPermissionTypes_result._Fields>, java.io.Serializable, Cloneable, Comparable<getPermissionTypes_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("getPermissionTypes_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new getPermissionTypes_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new getPermissionTypes_resultTupleSchemeFactory();

    public java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.PermissionType.class))));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(getPermissionTypes_result.class, metaDataMap);
    }

    public getPermissionTypes_result() {
    }

    public getPermissionTypes_result(
      java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public getPermissionTypes_result(getPermissionTypes_result other) {
      if (other.isSetSuccess()) {
        java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> __this__success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.PermissionType>(other.success.size());
        for (org.apache.airavata.sharing.registry.models.PermissionType other_element : other.success) {
          __this__success.add(new org.apache.airavata.sharing.registry.models.PermissionType(other_element));
        }
        this.success = __this__success;
      }
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public getPermissionTypes_result deepCopy() {
      return new getPermissionTypes_result(this);
    }

    @Override
    public void clear() {
      this.success = null;
      this.sre = null;
    }

    public int getSuccessSize() {
      return (this.success == null) ? 0 : this.success.size();
    }

    public java.util.Iterator<org.apache.airavata.sharing.registry.models.PermissionType> getSuccessIterator() {
      return (this.success == null) ? null : this.success.iterator();
    }

    public void addToSuccess(org.apache.airavata.sharing.registry.models.PermissionType elem) {
      if (this.success == null) {
        this.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.PermissionType>();
      }
      this.success.add(elem);
    }

    public java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> getSuccess() {
      return this.success;
    }

    public getPermissionTypes_result setSuccess(java.util.List<org.apache.airavata.sharing.registry.models.PermissionType> success) {
      this.success = success;
      return this;
    }

    public void unsetSuccess() {
      this.success = null;
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return this.success != null;
    }

    public void setSuccessIsSet(boolean value) {
      if (!value) {
        this.success = null;
      }
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public getPermissionTypes_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.util.List<org.apache.airavata.sharing.registry.models.PermissionType>)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return getSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof getPermissionTypes_result)
        return this.equals((getPermissionTypes_result)that);
      return false;
    }

    public boolean equals(getPermissionTypes_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true && this.isSetSuccess();
      boolean that_present_success = true && that.isSetSuccess();
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (!this.success.equals(that.success))
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
      if (isSetSuccess())
        hashCode = hashCode * 8191 + success.hashCode();

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(getPermissionTypes_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("getPermissionTypes_result(");
      boolean first = true;

      sb.append("success:");
      if (this.success == null) {
        sb.append("null");
      } else {
        sb.append(this.success);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        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 getPermissionTypes_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getPermissionTypes_resultStandardScheme getScheme() {
        return new getPermissionTypes_resultStandardScheme();
      }
    }

    private static class getPermissionTypes_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<getPermissionTypes_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, getPermissionTypes_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list144 = iprot.readListBegin();
                  struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.PermissionType>(_list144.size);
                  org.apache.airavata.sharing.registry.models.PermissionType _elem145;
                  for (int _i146 = 0; _i146 < _list144.size; ++_i146)
                  {
                    _elem145 = new org.apache.airavata.sharing.registry.models.PermissionType();
                    _elem145.read(iprot);
                    struct.success.add(_elem145);
                  }
                  iprot.readListEnd();
                }
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, getPermissionTypes_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.success != null) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
            for (org.apache.airavata.sharing.registry.models.PermissionType _iter147 : struct.success)
            {
              _iter147.write(oprot);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class getPermissionTypes_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public getPermissionTypes_resultTupleScheme getScheme() {
        return new getPermissionTypes_resultTupleScheme();
      }
    }

    private static class getPermissionTypes_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<getPermissionTypes_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, getPermissionTypes_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          {
            oprot.writeI32(struct.success.size());
            for (org.apache.airavata.sharing.registry.models.PermissionType _iter148 : struct.success)
            {
              _iter148.write(oprot);
            }
          }
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, getPermissionTypes_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          {
            org.apache.thrift.protocol.TList _list149 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            struct.success = new java.util.ArrayList<org.apache.airavata.sharing.registry.models.PermissionType>(_list149.size);
            org.apache.airavata.sharing.registry.models.PermissionType _elem150;
            for (int _i151 = 0; _i151 < _list149.size; ++_i151)
            {
              _elem150 = new org.apache.airavata.sharing.registry.models.PermissionType();
              _elem150.read(iprot);
              struct.success.add(_elem150);
            }
          }
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class shareEntityWithUsers_args implements org.apache.thrift.TBase<shareEntityWithUsers_args, shareEntityWithUsers_args._Fields>, java.io.Serializable, Cloneable, Comparable<shareEntityWithUsers_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("shareEntityWithUsers_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField USER_LIST_FIELD_DESC = new org.apache.thrift.protocol.TField("userList", org.apache.thrift.protocol.TType.LIST, (short)3);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField CASCADE_PERMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("cascadePermission", org.apache.thrift.protocol.TType.BOOL, (short)5);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new shareEntityWithUsers_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new shareEntityWithUsers_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required
    public java.util.List<java.lang.String> userList; // required
    public java.lang.String permissionTypeId; // required
    public boolean cascadePermission; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId"),
      USER_LIST((short)3, "userList"),
      PERMISSION_TYPE_ID((short)4, "permissionTypeId"),
      CASCADE_PERMISSION((short)5, "cascadePermission");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          case 3: // USER_LIST
            return USER_LIST;
          case 4: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          case 5: // CASCADE_PERMISSION
            return CASCADE_PERMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __CASCADEPERMISSION_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_LIST, new org.apache.thrift.meta_data.FieldMetaData("userList", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.CASCADE_PERMISSION, new org.apache.thrift.meta_data.FieldMetaData("cascadePermission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(shareEntityWithUsers_args.class, metaDataMap);
    }

    public shareEntityWithUsers_args() {
    }

    public shareEntityWithUsers_args(
      java.lang.String domainId,
      java.lang.String entityId,
      java.util.List<java.lang.String> userList,
      java.lang.String permissionTypeId,
      boolean cascadePermission)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
      this.userList = userList;
      this.permissionTypeId = permissionTypeId;
      this.cascadePermission = cascadePermission;
      setCascadePermissionIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public shareEntityWithUsers_args(shareEntityWithUsers_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetUserList()) {
        java.util.List<java.lang.String> __this__userList = new java.util.ArrayList<java.lang.String>(other.userList);
        this.userList = __this__userList;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
      this.cascadePermission = other.cascadePermission;
    }

    public shareEntityWithUsers_args deepCopy() {
      return new shareEntityWithUsers_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
      this.userList = null;
      this.permissionTypeId = null;
      setCascadePermissionIsSet(false);
      this.cascadePermission = false;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public shareEntityWithUsers_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public shareEntityWithUsers_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public int getUserListSize() {
      return (this.userList == null) ? 0 : this.userList.size();
    }

    public java.util.Iterator<java.lang.String> getUserListIterator() {
      return (this.userList == null) ? null : this.userList.iterator();
    }

    public void addToUserList(java.lang.String elem) {
      if (this.userList == null) {
        this.userList = new java.util.ArrayList<java.lang.String>();
      }
      this.userList.add(elem);
    }

    public java.util.List<java.lang.String> getUserList() {
      return this.userList;
    }

    public shareEntityWithUsers_args setUserList(java.util.List<java.lang.String> userList) {
      this.userList = userList;
      return this;
    }

    public void unsetUserList() {
      this.userList = null;
    }

    /** Returns true if field userList is set (has been assigned a value) and false otherwise */
    public boolean isSetUserList() {
      return this.userList != null;
    }

    public void setUserListIsSet(boolean value) {
      if (!value) {
        this.userList = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public shareEntityWithUsers_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public boolean isCascadePermission() {
      return this.cascadePermission;
    }

    public shareEntityWithUsers_args setCascadePermission(boolean cascadePermission) {
      this.cascadePermission = cascadePermission;
      setCascadePermissionIsSet(true);
      return this;
    }

    public void unsetCascadePermission() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CASCADEPERMISSION_ISSET_ID);
    }

    /** Returns true if field cascadePermission is set (has been assigned a value) and false otherwise */
    public boolean isSetCascadePermission() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CASCADEPERMISSION_ISSET_ID);
    }

    public void setCascadePermissionIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CASCADEPERMISSION_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case USER_LIST:
        if (value == null) {
          unsetUserList();
        } else {
          setUserList((java.util.List<java.lang.String>)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      case CASCADE_PERMISSION:
        if (value == null) {
          unsetCascadePermission();
        } else {
          setCascadePermission((java.lang.Boolean)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      case USER_LIST:
        return getUserList();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      case CASCADE_PERMISSION:
        return isCascadePermission();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      case USER_LIST:
        return isSetUserList();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      case CASCADE_PERMISSION:
        return isSetCascadePermission();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof shareEntityWithUsers_args)
        return this.equals((shareEntityWithUsers_args)that);
      return false;
    }

    public boolean equals(shareEntityWithUsers_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_userList = true && this.isSetUserList();
      boolean that_present_userList = true && that.isSetUserList();
      if (this_present_userList || that_present_userList) {
        if (!(this_present_userList && that_present_userList))
          return false;
        if (!this.userList.equals(that.userList))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      boolean this_present_cascadePermission = true;
      boolean that_present_cascadePermission = true;
      if (this_present_cascadePermission || that_present_cascadePermission) {
        if (!(this_present_cascadePermission && that_present_cascadePermission))
          return false;
        if (this.cascadePermission != that.cascadePermission)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserList()) ? 131071 : 524287);
      if (isSetUserList())
        hashCode = hashCode * 8191 + userList.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      hashCode = hashCode * 8191 + ((cascadePermission) ? 131071 : 524287);

      return hashCode;
    }

    @Override
    public int compareTo(shareEntityWithUsers_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserList()).compareTo(other.isSetUserList());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserList()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userList, other.userList);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetCascadePermission()).compareTo(other.isSetCascadePermission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCascadePermission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cascadePermission, other.cascadePermission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("shareEntityWithUsers_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userList:");
      if (this.userList == null) {
        sb.append("null");
      } else {
        sb.append(this.userList);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("cascadePermission:");
      sb.append(this.cascadePermission);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (userList == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userList' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'cascadePermission' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class shareEntityWithUsers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public shareEntityWithUsers_argsStandardScheme getScheme() {
        return new shareEntityWithUsers_argsStandardScheme();
      }
    }

    private static class shareEntityWithUsers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<shareEntityWithUsers_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, shareEntityWithUsers_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // USER_LIST
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list152 = iprot.readListBegin();
                  struct.userList = new java.util.ArrayList<java.lang.String>(_list152.size);
                  java.lang.String _elem153;
                  for (int _i154 = 0; _i154 < _list152.size; ++_i154)
                  {
                    _elem153 = iprot.readString();
                    struct.userList.add(_elem153);
                  }
                  iprot.readListEnd();
                }
                struct.setUserListIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // CASCADE_PERMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.cascadePermission = iprot.readBool();
                struct.setCascadePermissionIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetCascadePermission()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'cascadePermission' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, shareEntityWithUsers_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.userList != null) {
          oprot.writeFieldBegin(USER_LIST_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.userList.size()));
            for (java.lang.String _iter155 : struct.userList)
            {
              oprot.writeString(_iter155);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(CASCADE_PERMISSION_FIELD_DESC);
        oprot.writeBool(struct.cascadePermission);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class shareEntityWithUsers_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public shareEntityWithUsers_argsTupleScheme getScheme() {
        return new shareEntityWithUsers_argsTupleScheme();
      }
    }

    private static class shareEntityWithUsers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<shareEntityWithUsers_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, shareEntityWithUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
        {
          oprot.writeI32(struct.userList.size());
          for (java.lang.String _iter156 : struct.userList)
          {
            oprot.writeString(_iter156);
          }
        }
        oprot.writeString(struct.permissionTypeId);
        oprot.writeBool(struct.cascadePermission);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, shareEntityWithUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list157 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.userList = new java.util.ArrayList<java.lang.String>(_list157.size);
          java.lang.String _elem158;
          for (int _i159 = 0; _i159 < _list157.size; ++_i159)
          {
            _elem158 = iprot.readString();
            struct.userList.add(_elem158);
          }
        }
        struct.setUserListIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
        struct.cascadePermission = iprot.readBool();
        struct.setCascadePermissionIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class shareEntityWithUsers_result implements org.apache.thrift.TBase<shareEntityWithUsers_result, shareEntityWithUsers_result._Fields>, java.io.Serializable, Cloneable, Comparable<shareEntityWithUsers_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("shareEntityWithUsers_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new shareEntityWithUsers_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new shareEntityWithUsers_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(shareEntityWithUsers_result.class, metaDataMap);
    }

    public shareEntityWithUsers_result() {
    }

    public shareEntityWithUsers_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public shareEntityWithUsers_result(shareEntityWithUsers_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public shareEntityWithUsers_result deepCopy() {
      return new shareEntityWithUsers_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public shareEntityWithUsers_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public shareEntityWithUsers_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof shareEntityWithUsers_result)
        return this.equals((shareEntityWithUsers_result)that);
      return false;
    }

    public boolean equals(shareEntityWithUsers_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(shareEntityWithUsers_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("shareEntityWithUsers_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class shareEntityWithUsers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public shareEntityWithUsers_resultStandardScheme getScheme() {
        return new shareEntityWithUsers_resultStandardScheme();
      }
    }

    private static class shareEntityWithUsers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<shareEntityWithUsers_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, shareEntityWithUsers_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, shareEntityWithUsers_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class shareEntityWithUsers_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public shareEntityWithUsers_resultTupleScheme getScheme() {
        return new shareEntityWithUsers_resultTupleScheme();
      }
    }

    private static class shareEntityWithUsers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<shareEntityWithUsers_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, shareEntityWithUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, shareEntityWithUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class revokeEntitySharingFromUsers_args implements org.apache.thrift.TBase<revokeEntitySharingFromUsers_args, revokeEntitySharingFromUsers_args._Fields>, java.io.Serializable, Cloneable, Comparable<revokeEntitySharingFromUsers_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeEntitySharingFromUsers_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField USER_LIST_FIELD_DESC = new org.apache.thrift.protocol.TField("userList", org.apache.thrift.protocol.TType.LIST, (short)3);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)4);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeEntitySharingFromUsers_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeEntitySharingFromUsers_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required
    public java.util.List<java.lang.String> userList; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId"),
      USER_LIST((short)3, "userList"),
      PERMISSION_TYPE_ID((short)4, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          case 3: // USER_LIST
            return USER_LIST;
          case 4: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_LIST, new org.apache.thrift.meta_data.FieldMetaData("userList", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeEntitySharingFromUsers_args.class, metaDataMap);
    }

    public revokeEntitySharingFromUsers_args() {
    }

    public revokeEntitySharingFromUsers_args(
      java.lang.String domainId,
      java.lang.String entityId,
      java.util.List<java.lang.String> userList,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
      this.userList = userList;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeEntitySharingFromUsers_args(revokeEntitySharingFromUsers_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetUserList()) {
        java.util.List<java.lang.String> __this__userList = new java.util.ArrayList<java.lang.String>(other.userList);
        this.userList = __this__userList;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public revokeEntitySharingFromUsers_args deepCopy() {
      return new revokeEntitySharingFromUsers_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
      this.userList = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public revokeEntitySharingFromUsers_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public revokeEntitySharingFromUsers_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public int getUserListSize() {
      return (this.userList == null) ? 0 : this.userList.size();
    }

    public java.util.Iterator<java.lang.String> getUserListIterator() {
      return (this.userList == null) ? null : this.userList.iterator();
    }

    public void addToUserList(java.lang.String elem) {
      if (this.userList == null) {
        this.userList = new java.util.ArrayList<java.lang.String>();
      }
      this.userList.add(elem);
    }

    public java.util.List<java.lang.String> getUserList() {
      return this.userList;
    }

    public revokeEntitySharingFromUsers_args setUserList(java.util.List<java.lang.String> userList) {
      this.userList = userList;
      return this;
    }

    public void unsetUserList() {
      this.userList = null;
    }

    /** Returns true if field userList is set (has been assigned a value) and false otherwise */
    public boolean isSetUserList() {
      return this.userList != null;
    }

    public void setUserListIsSet(boolean value) {
      if (!value) {
        this.userList = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public revokeEntitySharingFromUsers_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case USER_LIST:
        if (value == null) {
          unsetUserList();
        } else {
          setUserList((java.util.List<java.lang.String>)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      case USER_LIST:
        return getUserList();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      case USER_LIST:
        return isSetUserList();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeEntitySharingFromUsers_args)
        return this.equals((revokeEntitySharingFromUsers_args)that);
      return false;
    }

    public boolean equals(revokeEntitySharingFromUsers_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_userList = true && this.isSetUserList();
      boolean that_present_userList = true && that.isSetUserList();
      if (this_present_userList || that_present_userList) {
        if (!(this_present_userList && that_present_userList))
          return false;
        if (!this.userList.equals(that.userList))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserList()) ? 131071 : 524287);
      if (isSetUserList())
        hashCode = hashCode * 8191 + userList.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(revokeEntitySharingFromUsers_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserList()).compareTo(other.isSetUserList());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserList()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userList, other.userList);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeEntitySharingFromUsers_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userList:");
      if (this.userList == null) {
        sb.append("null");
      } else {
        sb.append(this.userList);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (userList == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userList' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 revokeEntitySharingFromUsers_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeEntitySharingFromUsers_argsStandardScheme getScheme() {
        return new revokeEntitySharingFromUsers_argsStandardScheme();
      }
    }

    private static class revokeEntitySharingFromUsers_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<revokeEntitySharingFromUsers_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, revokeEntitySharingFromUsers_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // USER_LIST
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list160 = iprot.readListBegin();
                  struct.userList = new java.util.ArrayList<java.lang.String>(_list160.size);
                  java.lang.String _elem161;
                  for (int _i162 = 0; _i162 < _list160.size; ++_i162)
                  {
                    _elem161 = iprot.readString();
                    struct.userList.add(_elem161);
                  }
                  iprot.readListEnd();
                }
                struct.setUserListIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeEntitySharingFromUsers_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.userList != null) {
          oprot.writeFieldBegin(USER_LIST_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.userList.size()));
            for (java.lang.String _iter163 : struct.userList)
            {
              oprot.writeString(_iter163);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeEntitySharingFromUsers_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeEntitySharingFromUsers_argsTupleScheme getScheme() {
        return new revokeEntitySharingFromUsers_argsTupleScheme();
      }
    }

    private static class revokeEntitySharingFromUsers_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<revokeEntitySharingFromUsers_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, revokeEntitySharingFromUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
        {
          oprot.writeI32(struct.userList.size());
          for (java.lang.String _iter164 : struct.userList)
          {
            oprot.writeString(_iter164);
          }
        }
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeEntitySharingFromUsers_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list165 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.userList = new java.util.ArrayList<java.lang.String>(_list165.size);
          java.lang.String _elem166;
          for (int _i167 = 0; _i167 < _list165.size; ++_i167)
          {
            _elem166 = iprot.readString();
            struct.userList.add(_elem166);
          }
        }
        struct.setUserListIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class revokeEntitySharingFromUsers_result implements org.apache.thrift.TBase<revokeEntitySharingFromUsers_result, revokeEntitySharingFromUsers_result._Fields>, java.io.Serializable, Cloneable, Comparable<revokeEntitySharingFromUsers_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeEntitySharingFromUsers_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeEntitySharingFromUsers_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeEntitySharingFromUsers_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeEntitySharingFromUsers_result.class, metaDataMap);
    }

    public revokeEntitySharingFromUsers_result() {
    }

    public revokeEntitySharingFromUsers_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeEntitySharingFromUsers_result(revokeEntitySharingFromUsers_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public revokeEntitySharingFromUsers_result deepCopy() {
      return new revokeEntitySharingFromUsers_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public revokeEntitySharingFromUsers_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public revokeEntitySharingFromUsers_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeEntitySharingFromUsers_result)
        return this.equals((revokeEntitySharingFromUsers_result)that);
      return false;
    }

    public boolean equals(revokeEntitySharingFromUsers_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(revokeEntitySharingFromUsers_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeEntitySharingFromUsers_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class revokeEntitySharingFromUsers_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeEntitySharingFromUsers_resultStandardScheme getScheme() {
        return new revokeEntitySharingFromUsers_resultStandardScheme();
      }
    }

    private static class revokeEntitySharingFromUsers_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<revokeEntitySharingFromUsers_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, revokeEntitySharingFromUsers_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeEntitySharingFromUsers_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeEntitySharingFromUsers_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeEntitySharingFromUsers_resultTupleScheme getScheme() {
        return new revokeEntitySharingFromUsers_resultTupleScheme();
      }
    }

    private static class revokeEntitySharingFromUsers_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<revokeEntitySharingFromUsers_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, revokeEntitySharingFromUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeEntitySharingFromUsers_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class shareEntityWithGroups_args implements org.apache.thrift.TBase<shareEntityWithGroups_args, shareEntityWithGroups_args._Fields>, java.io.Serializable, Cloneable, Comparable<shareEntityWithGroups_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("shareEntityWithGroups_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField GROUP_LIST_FIELD_DESC = new org.apache.thrift.protocol.TField("groupList", org.apache.thrift.protocol.TType.LIST, (short)3);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)4);
    private static final org.apache.thrift.protocol.TField CASCADE_PERMISSION_FIELD_DESC = new org.apache.thrift.protocol.TField("cascadePermission", org.apache.thrift.protocol.TType.BOOL, (short)5);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new shareEntityWithGroups_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new shareEntityWithGroups_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required
    public java.util.List<java.lang.String> groupList; // required
    public java.lang.String permissionTypeId; // required
    public boolean cascadePermission; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId"),
      GROUP_LIST((short)3, "groupList"),
      PERMISSION_TYPE_ID((short)4, "permissionTypeId"),
      CASCADE_PERMISSION((short)5, "cascadePermission");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          case 3: // GROUP_LIST
            return GROUP_LIST;
          case 4: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          case 5: // CASCADE_PERMISSION
            return CASCADE_PERMISSION;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __CASCADEPERMISSION_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_LIST, new org.apache.thrift.meta_data.FieldMetaData("groupList", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.CASCADE_PERMISSION, new org.apache.thrift.meta_data.FieldMetaData("cascadePermission", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(shareEntityWithGroups_args.class, metaDataMap);
    }

    public shareEntityWithGroups_args() {
    }

    public shareEntityWithGroups_args(
      java.lang.String domainId,
      java.lang.String entityId,
      java.util.List<java.lang.String> groupList,
      java.lang.String permissionTypeId,
      boolean cascadePermission)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
      this.groupList = groupList;
      this.permissionTypeId = permissionTypeId;
      this.cascadePermission = cascadePermission;
      setCascadePermissionIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public shareEntityWithGroups_args(shareEntityWithGroups_args other) {
      __isset_bitfield = other.__isset_bitfield;
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetGroupList()) {
        java.util.List<java.lang.String> __this__groupList = new java.util.ArrayList<java.lang.String>(other.groupList);
        this.groupList = __this__groupList;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
      this.cascadePermission = other.cascadePermission;
    }

    public shareEntityWithGroups_args deepCopy() {
      return new shareEntityWithGroups_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
      this.groupList = null;
      this.permissionTypeId = null;
      setCascadePermissionIsSet(false);
      this.cascadePermission = false;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public shareEntityWithGroups_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public shareEntityWithGroups_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public int getGroupListSize() {
      return (this.groupList == null) ? 0 : this.groupList.size();
    }

    public java.util.Iterator<java.lang.String> getGroupListIterator() {
      return (this.groupList == null) ? null : this.groupList.iterator();
    }

    public void addToGroupList(java.lang.String elem) {
      if (this.groupList == null) {
        this.groupList = new java.util.ArrayList<java.lang.String>();
      }
      this.groupList.add(elem);
    }

    public java.util.List<java.lang.String> getGroupList() {
      return this.groupList;
    }

    public shareEntityWithGroups_args setGroupList(java.util.List<java.lang.String> groupList) {
      this.groupList = groupList;
      return this;
    }

    public void unsetGroupList() {
      this.groupList = null;
    }

    /** Returns true if field groupList is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupList() {
      return this.groupList != null;
    }

    public void setGroupListIsSet(boolean value) {
      if (!value) {
        this.groupList = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public shareEntityWithGroups_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public boolean isCascadePermission() {
      return this.cascadePermission;
    }

    public shareEntityWithGroups_args setCascadePermission(boolean cascadePermission) {
      this.cascadePermission = cascadePermission;
      setCascadePermissionIsSet(true);
      return this;
    }

    public void unsetCascadePermission() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __CASCADEPERMISSION_ISSET_ID);
    }

    /** Returns true if field cascadePermission is set (has been assigned a value) and false otherwise */
    public boolean isSetCascadePermission() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __CASCADEPERMISSION_ISSET_ID);
    }

    public void setCascadePermissionIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __CASCADEPERMISSION_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case GROUP_LIST:
        if (value == null) {
          unsetGroupList();
        } else {
          setGroupList((java.util.List<java.lang.String>)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      case CASCADE_PERMISSION:
        if (value == null) {
          unsetCascadePermission();
        } else {
          setCascadePermission((java.lang.Boolean)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      case GROUP_LIST:
        return getGroupList();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      case CASCADE_PERMISSION:
        return isCascadePermission();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      case GROUP_LIST:
        return isSetGroupList();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      case CASCADE_PERMISSION:
        return isSetCascadePermission();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof shareEntityWithGroups_args)
        return this.equals((shareEntityWithGroups_args)that);
      return false;
    }

    public boolean equals(shareEntityWithGroups_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_groupList = true && this.isSetGroupList();
      boolean that_present_groupList = true && that.isSetGroupList();
      if (this_present_groupList || that_present_groupList) {
        if (!(this_present_groupList && that_present_groupList))
          return false;
        if (!this.groupList.equals(that.groupList))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      boolean this_present_cascadePermission = true;
      boolean that_present_cascadePermission = true;
      if (this_present_cascadePermission || that_present_cascadePermission) {
        if (!(this_present_cascadePermission && that_present_cascadePermission))
          return false;
        if (this.cascadePermission != that.cascadePermission)
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupList()) ? 131071 : 524287);
      if (isSetGroupList())
        hashCode = hashCode * 8191 + groupList.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      hashCode = hashCode * 8191 + ((cascadePermission) ? 131071 : 524287);

      return hashCode;
    }

    @Override
    public int compareTo(shareEntityWithGroups_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupList()).compareTo(other.isSetGroupList());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupList()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupList, other.groupList);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetCascadePermission()).compareTo(other.isSetCascadePermission());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetCascadePermission()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.cascadePermission, other.cascadePermission);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("shareEntityWithGroups_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupList:");
      if (this.groupList == null) {
        sb.append("null");
      } else {
        sb.append(this.groupList);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("cascadePermission:");
      sb.append(this.cascadePermission);
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (groupList == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupList' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // alas, we cannot check 'cascadePermission' because it's a primitive and you chose the non-beans generator.
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class shareEntityWithGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public shareEntityWithGroups_argsStandardScheme getScheme() {
        return new shareEntityWithGroups_argsStandardScheme();
      }
    }

    private static class shareEntityWithGroups_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<shareEntityWithGroups_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, shareEntityWithGroups_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GROUP_LIST
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list168 = iprot.readListBegin();
                  struct.groupList = new java.util.ArrayList<java.lang.String>(_list168.size);
                  java.lang.String _elem169;
                  for (int _i170 = 0; _i170 < _list168.size; ++_i170)
                  {
                    _elem169 = iprot.readString();
                    struct.groupList.add(_elem169);
                  }
                  iprot.readListEnd();
                }
                struct.setGroupListIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 5: // CASCADE_PERMISSION
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.cascadePermission = iprot.readBool();
                struct.setCascadePermissionIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        if (!struct.isSetCascadePermission()) {
          throw new org.apache.thrift.protocol.TProtocolException("Required field 'cascadePermission' was not found in serialized data! Struct: " + toString());
        }
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, shareEntityWithGroups_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.groupList != null) {
          oprot.writeFieldBegin(GROUP_LIST_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.groupList.size()));
            for (java.lang.String _iter171 : struct.groupList)
            {
              oprot.writeString(_iter171);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldBegin(CASCADE_PERMISSION_FIELD_DESC);
        oprot.writeBool(struct.cascadePermission);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class shareEntityWithGroups_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public shareEntityWithGroups_argsTupleScheme getScheme() {
        return new shareEntityWithGroups_argsTupleScheme();
      }
    }

    private static class shareEntityWithGroups_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<shareEntityWithGroups_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, shareEntityWithGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
        {
          oprot.writeI32(struct.groupList.size());
          for (java.lang.String _iter172 : struct.groupList)
          {
            oprot.writeString(_iter172);
          }
        }
        oprot.writeString(struct.permissionTypeId);
        oprot.writeBool(struct.cascadePermission);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, shareEntityWithGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list173 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.groupList = new java.util.ArrayList<java.lang.String>(_list173.size);
          java.lang.String _elem174;
          for (int _i175 = 0; _i175 < _list173.size; ++_i175)
          {
            _elem174 = iprot.readString();
            struct.groupList.add(_elem174);
          }
        }
        struct.setGroupListIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
        struct.cascadePermission = iprot.readBool();
        struct.setCascadePermissionIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class shareEntityWithGroups_result implements org.apache.thrift.TBase<shareEntityWithGroups_result, shareEntityWithGroups_result._Fields>, java.io.Serializable, Cloneable, Comparable<shareEntityWithGroups_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("shareEntityWithGroups_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new shareEntityWithGroups_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new shareEntityWithGroups_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(shareEntityWithGroups_result.class, metaDataMap);
    }

    public shareEntityWithGroups_result() {
    }

    public shareEntityWithGroups_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public shareEntityWithGroups_result(shareEntityWithGroups_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public shareEntityWithGroups_result deepCopy() {
      return new shareEntityWithGroups_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public shareEntityWithGroups_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public shareEntityWithGroups_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof shareEntityWithGroups_result)
        return this.equals((shareEntityWithGroups_result)that);
      return false;
    }

    public boolean equals(shareEntityWithGroups_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(shareEntityWithGroups_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("shareEntityWithGroups_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class shareEntityWithGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public shareEntityWithGroups_resultStandardScheme getScheme() {
        return new shareEntityWithGroups_resultStandardScheme();
      }
    }

    private static class shareEntityWithGroups_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<shareEntityWithGroups_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, shareEntityWithGroups_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, shareEntityWithGroups_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class shareEntityWithGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public shareEntityWithGroups_resultTupleScheme getScheme() {
        return new shareEntityWithGroups_resultTupleScheme();
      }
    }

    private static class shareEntityWithGroups_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<shareEntityWithGroups_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, shareEntityWithGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, shareEntityWithGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class revokeEntitySharingFromGroups_args implements org.apache.thrift.TBase<revokeEntitySharingFromGroups_args, revokeEntitySharingFromGroups_args._Fields>, java.io.Serializable, Cloneable, Comparable<revokeEntitySharingFromGroups_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeEntitySharingFromGroups_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField GROUP_LIST_FIELD_DESC = new org.apache.thrift.protocol.TField("groupList", org.apache.thrift.protocol.TType.LIST, (short)3);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)4);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeEntitySharingFromGroups_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeEntitySharingFromGroups_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String entityId; // required
    public java.util.List<java.lang.String> groupList; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      ENTITY_ID((short)2, "entityId"),
      GROUP_LIST((short)3, "groupList"),
      PERMISSION_TYPE_ID((short)4, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // ENTITY_ID
            return ENTITY_ID;
          case 3: // GROUP_LIST
            return GROUP_LIST;
          case 4: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.GROUP_LIST, new org.apache.thrift.meta_data.FieldMetaData("groupList", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          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.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeEntitySharingFromGroups_args.class, metaDataMap);
    }

    public revokeEntitySharingFromGroups_args() {
    }

    public revokeEntitySharingFromGroups_args(
      java.lang.String domainId,
      java.lang.String entityId,
      java.util.List<java.lang.String> groupList,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.entityId = entityId;
      this.groupList = groupList;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeEntitySharingFromGroups_args(revokeEntitySharingFromGroups_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetGroupList()) {
        java.util.List<java.lang.String> __this__groupList = new java.util.ArrayList<java.lang.String>(other.groupList);
        this.groupList = __this__groupList;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public revokeEntitySharingFromGroups_args deepCopy() {
      return new revokeEntitySharingFromGroups_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.entityId = null;
      this.groupList = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public revokeEntitySharingFromGroups_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public revokeEntitySharingFromGroups_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public int getGroupListSize() {
      return (this.groupList == null) ? 0 : this.groupList.size();
    }

    public java.util.Iterator<java.lang.String> getGroupListIterator() {
      return (this.groupList == null) ? null : this.groupList.iterator();
    }

    public void addToGroupList(java.lang.String elem) {
      if (this.groupList == null) {
        this.groupList = new java.util.ArrayList<java.lang.String>();
      }
      this.groupList.add(elem);
    }

    public java.util.List<java.lang.String> getGroupList() {
      return this.groupList;
    }

    public revokeEntitySharingFromGroups_args setGroupList(java.util.List<java.lang.String> groupList) {
      this.groupList = groupList;
      return this;
    }

    public void unsetGroupList() {
      this.groupList = null;
    }

    /** Returns true if field groupList is set (has been assigned a value) and false otherwise */
    public boolean isSetGroupList() {
      return this.groupList != null;
    }

    public void setGroupListIsSet(boolean value) {
      if (!value) {
        this.groupList = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public revokeEntitySharingFromGroups_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case GROUP_LIST:
        if (value == null) {
          unsetGroupList();
        } else {
          setGroupList((java.util.List<java.lang.String>)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case ENTITY_ID:
        return getEntityId();

      case GROUP_LIST:
        return getGroupList();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case ENTITY_ID:
        return isSetEntityId();
      case GROUP_LIST:
        return isSetGroupList();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeEntitySharingFromGroups_args)
        return this.equals((revokeEntitySharingFromGroups_args)that);
      return false;
    }

    public boolean equals(revokeEntitySharingFromGroups_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_groupList = true && this.isSetGroupList();
      boolean that_present_groupList = true && that.isSetGroupList();
      if (this_present_groupList || that_present_groupList) {
        if (!(this_present_groupList && that_present_groupList))
          return false;
        if (!this.groupList.equals(that.groupList))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetGroupList()) ? 131071 : 524287);
      if (isSetGroupList())
        hashCode = hashCode * 8191 + groupList.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(revokeEntitySharingFromGroups_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetGroupList()).compareTo(other.isSetGroupList());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetGroupList()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.groupList, other.groupList);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeEntitySharingFromGroups_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("groupList:");
      if (this.groupList == null) {
        sb.append("null");
      } else {
        sb.append(this.groupList);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (groupList == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'groupList' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 revokeEntitySharingFromGroups_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeEntitySharingFromGroups_argsStandardScheme getScheme() {
        return new revokeEntitySharingFromGroups_argsStandardScheme();
      }
    }

    private static class revokeEntitySharingFromGroups_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<revokeEntitySharingFromGroups_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, revokeEntitySharingFromGroups_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // GROUP_LIST
              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
                {
                  org.apache.thrift.protocol.TList _list176 = iprot.readListBegin();
                  struct.groupList = new java.util.ArrayList<java.lang.String>(_list176.size);
                  java.lang.String _elem177;
                  for (int _i178 = 0; _i178 < _list176.size; ++_i178)
                  {
                    _elem177 = iprot.readString();
                    struct.groupList.add(_elem177);
                  }
                  iprot.readListEnd();
                }
                struct.setGroupListIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeEntitySharingFromGroups_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.groupList != null) {
          oprot.writeFieldBegin(GROUP_LIST_FIELD_DESC);
          {
            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, struct.groupList.size()));
            for (java.lang.String _iter179 : struct.groupList)
            {
              oprot.writeString(_iter179);
            }
            oprot.writeListEnd();
          }
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeEntitySharingFromGroups_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeEntitySharingFromGroups_argsTupleScheme getScheme() {
        return new revokeEntitySharingFromGroups_argsTupleScheme();
      }
    }

    private static class revokeEntitySharingFromGroups_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<revokeEntitySharingFromGroups_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, revokeEntitySharingFromGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.entityId);
        {
          oprot.writeI32(struct.groupList.size());
          for (java.lang.String _iter180 : struct.groupList)
          {
            oprot.writeString(_iter180);
          }
        }
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeEntitySharingFromGroups_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        {
          org.apache.thrift.protocol.TList _list181 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRING, iprot.readI32());
          struct.groupList = new java.util.ArrayList<java.lang.String>(_list181.size);
          java.lang.String _elem182;
          for (int _i183 = 0; _i183 < _list181.size; ++_i183)
          {
            _elem182 = iprot.readString();
            struct.groupList.add(_elem182);
          }
        }
        struct.setGroupListIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class revokeEntitySharingFromGroups_result implements org.apache.thrift.TBase<revokeEntitySharingFromGroups_result, revokeEntitySharingFromGroups_result._Fields>, java.io.Serializable, Cloneable, Comparable<revokeEntitySharingFromGroups_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("revokeEntitySharingFromGroups_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new revokeEntitySharingFromGroups_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new revokeEntitySharingFromGroups_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(revokeEntitySharingFromGroups_result.class, metaDataMap);
    }

    public revokeEntitySharingFromGroups_result() {
    }

    public revokeEntitySharingFromGroups_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public revokeEntitySharingFromGroups_result(revokeEntitySharingFromGroups_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public revokeEntitySharingFromGroups_result deepCopy() {
      return new revokeEntitySharingFromGroups_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public revokeEntitySharingFromGroups_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public revokeEntitySharingFromGroups_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof revokeEntitySharingFromGroups_result)
        return this.equals((revokeEntitySharingFromGroups_result)that);
      return false;
    }

    public boolean equals(revokeEntitySharingFromGroups_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(revokeEntitySharingFromGroups_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("revokeEntitySharingFromGroups_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class revokeEntitySharingFromGroups_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeEntitySharingFromGroups_resultStandardScheme getScheme() {
        return new revokeEntitySharingFromGroups_resultStandardScheme();
      }
    }

    private static class revokeEntitySharingFromGroups_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<revokeEntitySharingFromGroups_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, revokeEntitySharingFromGroups_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, revokeEntitySharingFromGroups_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class revokeEntitySharingFromGroups_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public revokeEntitySharingFromGroups_resultTupleScheme getScheme() {
        return new revokeEntitySharingFromGroups_resultTupleScheme();
      }
    }

    private static class revokeEntitySharingFromGroups_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<revokeEntitySharingFromGroups_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, revokeEntitySharingFromGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, revokeEntitySharingFromGroups_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class userHasAccess_args implements org.apache.thrift.TBase<userHasAccess_args, userHasAccess_args._Fields>, java.io.Serializable, Cloneable, Comparable<userHasAccess_args>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("userHasAccess_args");

    private static final org.apache.thrift.protocol.TField DOMAIN_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("domainId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField USER_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("userId", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField ENTITY_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("entityId", org.apache.thrift.protocol.TType.STRING, (short)3);
    private static final org.apache.thrift.protocol.TField PERMISSION_TYPE_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("permissionTypeId", org.apache.thrift.protocol.TType.STRING, (short)4);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new userHasAccess_argsStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new userHasAccess_argsTupleSchemeFactory();

    public java.lang.String domainId; // required
    public java.lang.String userId; // required
    public java.lang.String entityId; // required
    public java.lang.String permissionTypeId; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      DOMAIN_ID((short)1, "domainId"),
      USER_ID((short)2, "userId"),
      ENTITY_ID((short)3, "entityId"),
      PERMISSION_TYPE_ID((short)4, "permissionTypeId");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 1: // DOMAIN_ID
            return DOMAIN_ID;
          case 2: // USER_ID
            return USER_ID;
          case 3: // ENTITY_ID
            return ENTITY_ID;
          case 4: // PERMISSION_TYPE_ID
            return PERMISSION_TYPE_ID;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.DOMAIN_ID, new org.apache.thrift.meta_data.FieldMetaData("domainId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.USER_ID, new org.apache.thrift.meta_data.FieldMetaData("userId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.ENTITY_ID, new org.apache.thrift.meta_data.FieldMetaData("entityId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      tmpMap.put(_Fields.PERMISSION_TYPE_ID, new org.apache.thrift.meta_data.FieldMetaData("permissionTypeId", org.apache.thrift.TFieldRequirementType.REQUIRED, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(userHasAccess_args.class, metaDataMap);
    }

    public userHasAccess_args() {
    }

    public userHasAccess_args(
      java.lang.String domainId,
      java.lang.String userId,
      java.lang.String entityId,
      java.lang.String permissionTypeId)
    {
      this();
      this.domainId = domainId;
      this.userId = userId;
      this.entityId = entityId;
      this.permissionTypeId = permissionTypeId;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public userHasAccess_args(userHasAccess_args other) {
      if (other.isSetDomainId()) {
        this.domainId = other.domainId;
      }
      if (other.isSetUserId()) {
        this.userId = other.userId;
      }
      if (other.isSetEntityId()) {
        this.entityId = other.entityId;
      }
      if (other.isSetPermissionTypeId()) {
        this.permissionTypeId = other.permissionTypeId;
      }
    }

    public userHasAccess_args deepCopy() {
      return new userHasAccess_args(this);
    }

    @Override
    public void clear() {
      this.domainId = null;
      this.userId = null;
      this.entityId = null;
      this.permissionTypeId = null;
    }

    public java.lang.String getDomainId() {
      return this.domainId;
    }

    public userHasAccess_args setDomainId(java.lang.String domainId) {
      this.domainId = domainId;
      return this;
    }

    public void unsetDomainId() {
      this.domainId = null;
    }

    /** Returns true if field domainId is set (has been assigned a value) and false otherwise */
    public boolean isSetDomainId() {
      return this.domainId != null;
    }

    public void setDomainIdIsSet(boolean value) {
      if (!value) {
        this.domainId = null;
      }
    }

    public java.lang.String getUserId() {
      return this.userId;
    }

    public userHasAccess_args setUserId(java.lang.String userId) {
      this.userId = userId;
      return this;
    }

    public void unsetUserId() {
      this.userId = null;
    }

    /** Returns true if field userId is set (has been assigned a value) and false otherwise */
    public boolean isSetUserId() {
      return this.userId != null;
    }

    public void setUserIdIsSet(boolean value) {
      if (!value) {
        this.userId = null;
      }
    }

    public java.lang.String getEntityId() {
      return this.entityId;
    }

    public userHasAccess_args setEntityId(java.lang.String entityId) {
      this.entityId = entityId;
      return this;
    }

    public void unsetEntityId() {
      this.entityId = null;
    }

    /** Returns true if field entityId is set (has been assigned a value) and false otherwise */
    public boolean isSetEntityId() {
      return this.entityId != null;
    }

    public void setEntityIdIsSet(boolean value) {
      if (!value) {
        this.entityId = null;
      }
    }

    public java.lang.String getPermissionTypeId() {
      return this.permissionTypeId;
    }

    public userHasAccess_args setPermissionTypeId(java.lang.String permissionTypeId) {
      this.permissionTypeId = permissionTypeId;
      return this;
    }

    public void unsetPermissionTypeId() {
      this.permissionTypeId = null;
    }

    /** Returns true if field permissionTypeId is set (has been assigned a value) and false otherwise */
    public boolean isSetPermissionTypeId() {
      return this.permissionTypeId != null;
    }

    public void setPermissionTypeIdIsSet(boolean value) {
      if (!value) {
        this.permissionTypeId = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case DOMAIN_ID:
        if (value == null) {
          unsetDomainId();
        } else {
          setDomainId((java.lang.String)value);
        }
        break;

      case USER_ID:
        if (value == null) {
          unsetUserId();
        } else {
          setUserId((java.lang.String)value);
        }
        break;

      case ENTITY_ID:
        if (value == null) {
          unsetEntityId();
        } else {
          setEntityId((java.lang.String)value);
        }
        break;

      case PERMISSION_TYPE_ID:
        if (value == null) {
          unsetPermissionTypeId();
        } else {
          setPermissionTypeId((java.lang.String)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case DOMAIN_ID:
        return getDomainId();

      case USER_ID:
        return getUserId();

      case ENTITY_ID:
        return getEntityId();

      case PERMISSION_TYPE_ID:
        return getPermissionTypeId();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case DOMAIN_ID:
        return isSetDomainId();
      case USER_ID:
        return isSetUserId();
      case ENTITY_ID:
        return isSetEntityId();
      case PERMISSION_TYPE_ID:
        return isSetPermissionTypeId();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof userHasAccess_args)
        return this.equals((userHasAccess_args)that);
      return false;
    }

    public boolean equals(userHasAccess_args that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_domainId = true && this.isSetDomainId();
      boolean that_present_domainId = true && that.isSetDomainId();
      if (this_present_domainId || that_present_domainId) {
        if (!(this_present_domainId && that_present_domainId))
          return false;
        if (!this.domainId.equals(that.domainId))
          return false;
      }

      boolean this_present_userId = true && this.isSetUserId();
      boolean that_present_userId = true && that.isSetUserId();
      if (this_present_userId || that_present_userId) {
        if (!(this_present_userId && that_present_userId))
          return false;
        if (!this.userId.equals(that.userId))
          return false;
      }

      boolean this_present_entityId = true && this.isSetEntityId();
      boolean that_present_entityId = true && that.isSetEntityId();
      if (this_present_entityId || that_present_entityId) {
        if (!(this_present_entityId && that_present_entityId))
          return false;
        if (!this.entityId.equals(that.entityId))
          return false;
      }

      boolean this_present_permissionTypeId = true && this.isSetPermissionTypeId();
      boolean that_present_permissionTypeId = true && that.isSetPermissionTypeId();
      if (this_present_permissionTypeId || that_present_permissionTypeId) {
        if (!(this_present_permissionTypeId && that_present_permissionTypeId))
          return false;
        if (!this.permissionTypeId.equals(that.permissionTypeId))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((isSetDomainId()) ? 131071 : 524287);
      if (isSetDomainId())
        hashCode = hashCode * 8191 + domainId.hashCode();

      hashCode = hashCode * 8191 + ((isSetUserId()) ? 131071 : 524287);
      if (isSetUserId())
        hashCode = hashCode * 8191 + userId.hashCode();

      hashCode = hashCode * 8191 + ((isSetEntityId()) ? 131071 : 524287);
      if (isSetEntityId())
        hashCode = hashCode * 8191 + entityId.hashCode();

      hashCode = hashCode * 8191 + ((isSetPermissionTypeId()) ? 131071 : 524287);
      if (isSetPermissionTypeId())
        hashCode = hashCode * 8191 + permissionTypeId.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(userHasAccess_args other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetDomainId()).compareTo(other.isSetDomainId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetDomainId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.domainId, other.domainId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetUserId()).compareTo(other.isSetUserId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetUserId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.userId, other.userId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetEntityId()).compareTo(other.isSetEntityId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetEntityId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityId, other.entityId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetPermissionTypeId()).compareTo(other.isSetPermissionTypeId());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetPermissionTypeId()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.permissionTypeId, other.permissionTypeId);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
    }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("userHasAccess_args(");
      boolean first = true;

      sb.append("domainId:");
      if (this.domainId == null) {
        sb.append("null");
      } else {
        sb.append(this.domainId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("userId:");
      if (this.userId == null) {
        sb.append("null");
      } else {
        sb.append(this.userId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("entityId:");
      if (this.entityId == null) {
        sb.append("null");
      } else {
        sb.append(this.entityId);
      }
      first = false;
      if (!first) sb.append(", ");
      sb.append("permissionTypeId:");
      if (this.permissionTypeId == null) {
        sb.append("null");
      } else {
        sb.append(this.permissionTypeId);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      if (domainId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'domainId' was not present! Struct: " + toString());
      }
      if (userId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'userId' was not present! Struct: " + toString());
      }
      if (entityId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityId' was not present! Struct: " + toString());
      }
      if (permissionTypeId == null) {
        throw new org.apache.thrift.protocol.TProtocolException("Required field 'permissionTypeId' was not present! Struct: " + toString());
      }
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.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 userHasAccess_argsStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public userHasAccess_argsStandardScheme getScheme() {
        return new userHasAccess_argsStandardScheme();
      }
    }

    private static class userHasAccess_argsStandardScheme extends org.apache.thrift.scheme.StandardScheme<userHasAccess_args> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, userHasAccess_args 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: // DOMAIN_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.domainId = iprot.readString();
                struct.setDomainIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 2: // USER_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.userId = iprot.readString();
                struct.setUserIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 3: // ENTITY_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.entityId = iprot.readString();
                struct.setEntityIdIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 4: // PERMISSION_TYPE_ID
              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                struct.permissionTypeId = iprot.readString();
                struct.setPermissionTypeIdIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, userHasAccess_args struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.domainId != null) {
          oprot.writeFieldBegin(DOMAIN_ID_FIELD_DESC);
          oprot.writeString(struct.domainId);
          oprot.writeFieldEnd();
        }
        if (struct.userId != null) {
          oprot.writeFieldBegin(USER_ID_FIELD_DESC);
          oprot.writeString(struct.userId);
          oprot.writeFieldEnd();
        }
        if (struct.entityId != null) {
          oprot.writeFieldBegin(ENTITY_ID_FIELD_DESC);
          oprot.writeString(struct.entityId);
          oprot.writeFieldEnd();
        }
        if (struct.permissionTypeId != null) {
          oprot.writeFieldBegin(PERMISSION_TYPE_ID_FIELD_DESC);
          oprot.writeString(struct.permissionTypeId);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class userHasAccess_argsTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public userHasAccess_argsTupleScheme getScheme() {
        return new userHasAccess_argsTupleScheme();
      }
    }

    private static class userHasAccess_argsTupleScheme extends org.apache.thrift.scheme.TupleScheme<userHasAccess_args> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, userHasAccess_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        oprot.writeString(struct.domainId);
        oprot.writeString(struct.userId);
        oprot.writeString(struct.entityId);
        oprot.writeString(struct.permissionTypeId);
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, userHasAccess_args struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        struct.domainId = iprot.readString();
        struct.setDomainIdIsSet(true);
        struct.userId = iprot.readString();
        struct.setUserIdIsSet(true);
        struct.entityId = iprot.readString();
        struct.setEntityIdIsSet(true);
        struct.permissionTypeId = iprot.readString();
        struct.setPermissionTypeIdIsSet(true);
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

  public static class userHasAccess_result implements org.apache.thrift.TBase<userHasAccess_result, userHasAccess_result._Fields>, java.io.Serializable, Cloneable, Comparable<userHasAccess_result>   {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("userHasAccess_result");

    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.BOOL, (short)0);
    private static final org.apache.thrift.protocol.TField SRE_FIELD_DESC = new org.apache.thrift.protocol.TField("sre", org.apache.thrift.protocol.TType.STRUCT, (short)1);

    private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new userHasAccess_resultStandardSchemeFactory();
    private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new userHasAccess_resultTupleSchemeFactory();

    public boolean success; // required
    public org.apache.airavata.sharing.registry.models.SharingRegistryException sre; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
      SUCCESS((short)0, "success"),
      SRE((short)1, "sre");

      private static final java.util.Map<java.lang.String, _Fields> byName = new java.util.HashMap<java.lang.String, _Fields>();

      static {
        for (_Fields field : java.util.EnumSet.allOf(_Fields.class)) {
          byName.put(field.getFieldName(), field);
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, or null if its not found.
       */
      public static _Fields findByThriftId(int fieldId) {
        switch(fieldId) {
          case 0: // SUCCESS
            return SUCCESS;
          case 1: // SRE
            return SRE;
          default:
            return null;
        }
      }

      /**
       * Find the _Fields constant that matches fieldId, throwing an exception
       * if it is not found.
       */
      public static _Fields findByThriftIdOrThrow(int fieldId) {
        _Fields fields = findByThriftId(fieldId);
        if (fields == null) throw new java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
        return fields;
      }

      /**
       * Find the _Fields constant that matches name, or null if its not found.
       */
      public static _Fields findByName(java.lang.String name) {
        return byName.get(name);
      }

      private final short _thriftId;
      private final java.lang.String _fieldName;

      _Fields(short thriftId, java.lang.String fieldName) {
        _thriftId = thriftId;
        _fieldName = fieldName;
      }

      public short getThriftFieldId() {
        return _thriftId;
      }

      public java.lang.String getFieldName() {
        return _fieldName;
      }
    }

    // isset id assignments
    private static final int __SUCCESS_ISSET_ID = 0;
    private byte __isset_bitfield = 0;
    public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
      java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
      tmpMap.put(_Fields.SRE, new org.apache.thrift.meta_data.FieldMetaData("sre", org.apache.thrift.TFieldRequirementType.DEFAULT, 
          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.airavata.sharing.registry.models.SharingRegistryException.class)));
      metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(userHasAccess_result.class, metaDataMap);
    }

    public userHasAccess_result() {
    }

    public userHasAccess_result(
      boolean success,
      org.apache.airavata.sharing.registry.models.SharingRegistryException sre)
    {
      this();
      this.success = success;
      setSuccessIsSet(true);
      this.sre = sre;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public userHasAccess_result(userHasAccess_result other) {
      __isset_bitfield = other.__isset_bitfield;
      this.success = other.success;
      if (other.isSetSre()) {
        this.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException(other.sre);
      }
    }

    public userHasAccess_result deepCopy() {
      return new userHasAccess_result(this);
    }

    @Override
    public void clear() {
      setSuccessIsSet(false);
      this.success = false;
      this.sre = null;
    }

    public boolean isSuccess() {
      return this.success;
    }

    public userHasAccess_result setSuccess(boolean success) {
      this.success = success;
      setSuccessIsSet(true);
      return this;
    }

    public void unsetSuccess() {
      __isset_bitfield = org.apache.thrift.EncodingUtils.clearBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    /** Returns true if field success is set (has been assigned a value) and false otherwise */
    public boolean isSetSuccess() {
      return org.apache.thrift.EncodingUtils.testBit(__isset_bitfield, __SUCCESS_ISSET_ID);
    }

    public void setSuccessIsSet(boolean value) {
      __isset_bitfield = org.apache.thrift.EncodingUtils.setBit(__isset_bitfield, __SUCCESS_ISSET_ID, value);
    }

    public org.apache.airavata.sharing.registry.models.SharingRegistryException getSre() {
      return this.sre;
    }

    public userHasAccess_result setSre(org.apache.airavata.sharing.registry.models.SharingRegistryException sre) {
      this.sre = sre;
      return this;
    }

    public void unsetSre() {
      this.sre = null;
    }

    /** Returns true if field sre is set (has been assigned a value) and false otherwise */
    public boolean isSetSre() {
      return this.sre != null;
    }

    public void setSreIsSet(boolean value) {
      if (!value) {
        this.sre = null;
      }
    }

    public void setFieldValue(_Fields field, java.lang.Object value) {
      switch (field) {
      case SUCCESS:
        if (value == null) {
          unsetSuccess();
        } else {
          setSuccess((java.lang.Boolean)value);
        }
        break;

      case SRE:
        if (value == null) {
          unsetSre();
        } else {
          setSre((org.apache.airavata.sharing.registry.models.SharingRegistryException)value);
        }
        break;

      }
    }

    public java.lang.Object getFieldValue(_Fields field) {
      switch (field) {
      case SUCCESS:
        return isSuccess();

      case SRE:
        return getSre();

      }
      throw new java.lang.IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
      if (field == null) {
        throw new java.lang.IllegalArgumentException();
      }

      switch (field) {
      case SUCCESS:
        return isSetSuccess();
      case SRE:
        return isSetSre();
      }
      throw new java.lang.IllegalStateException();
    }

    @Override
    public boolean equals(java.lang.Object that) {
      if (that == null)
        return false;
      if (that instanceof userHasAccess_result)
        return this.equals((userHasAccess_result)that);
      return false;
    }

    public boolean equals(userHasAccess_result that) {
      if (that == null)
        return false;
      if (this == that)
        return true;

      boolean this_present_success = true;
      boolean that_present_success = true;
      if (this_present_success || that_present_success) {
        if (!(this_present_success && that_present_success))
          return false;
        if (this.success != that.success)
          return false;
      }

      boolean this_present_sre = true && this.isSetSre();
      boolean that_present_sre = true && that.isSetSre();
      if (this_present_sre || that_present_sre) {
        if (!(this_present_sre && that_present_sre))
          return false;
        if (!this.sre.equals(that.sre))
          return false;
      }

      return true;
    }

    @Override
    public int hashCode() {
      int hashCode = 1;

      hashCode = hashCode * 8191 + ((success) ? 131071 : 524287);

      hashCode = hashCode * 8191 + ((isSetSre()) ? 131071 : 524287);
      if (isSetSre())
        hashCode = hashCode * 8191 + sre.hashCode();

      return hashCode;
    }

    @Override
    public int compareTo(userHasAccess_result other) {
      if (!getClass().equals(other.getClass())) {
        return getClass().getName().compareTo(other.getClass().getName());
      }

      int lastComparison = 0;

      lastComparison = java.lang.Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSuccess()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      lastComparison = java.lang.Boolean.valueOf(isSetSre()).compareTo(other.isSetSre());
      if (lastComparison != 0) {
        return lastComparison;
      }
      if (isSetSre()) {
        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.sre, other.sre);
        if (lastComparison != 0) {
          return lastComparison;
        }
      }
      return 0;
    }

    public _Fields fieldForId(int fieldId) {
      return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
      scheme(iprot).read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
      scheme(oprot).write(oprot, this);
      }

    @Override
    public java.lang.String toString() {
      java.lang.StringBuilder sb = new java.lang.StringBuilder("userHasAccess_result(");
      boolean first = true;

      sb.append("success:");
      sb.append(this.success);
      first = false;
      if (!first) sb.append(", ");
      sb.append("sre:");
      if (this.sre == null) {
        sb.append("null");
      } else {
        sb.append(this.sre);
      }
      first = false;
      sb.append(")");
      return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
      // check for required fields
      // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
      try {
        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException {
      try {
        // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
        __isset_bitfield = 0;
        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
      } catch (org.apache.thrift.TException te) {
        throw new java.io.IOException(te);
      }
    }

    private static class userHasAccess_resultStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public userHasAccess_resultStandardScheme getScheme() {
        return new userHasAccess_resultStandardScheme();
      }
    }

    private static class userHasAccess_resultStandardScheme extends org.apache.thrift.scheme.StandardScheme<userHasAccess_result> {

      public void read(org.apache.thrift.protocol.TProtocol iprot, userHasAccess_result 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 0: // SUCCESS
              if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
                struct.success = iprot.readBool();
                struct.setSuccessIsSet(true);
              } else { 
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
              }
              break;
            case 1: // SRE
              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
                struct.sre.read(iprot);
                struct.setSreIsSet(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();

        // check for required fields of primitive type, which can't be checked in the validate method
        struct.validate();
      }

      public void write(org.apache.thrift.protocol.TProtocol oprot, userHasAccess_result struct) throws org.apache.thrift.TException {
        struct.validate();

        oprot.writeStructBegin(STRUCT_DESC);
        if (struct.isSetSuccess()) {
          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
          oprot.writeBool(struct.success);
          oprot.writeFieldEnd();
        }
        if (struct.sre != null) {
          oprot.writeFieldBegin(SRE_FIELD_DESC);
          struct.sre.write(oprot);
          oprot.writeFieldEnd();
        }
        oprot.writeFieldStop();
        oprot.writeStructEnd();
      }

    }

    private static class userHasAccess_resultTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
      public userHasAccess_resultTupleScheme getScheme() {
        return new userHasAccess_resultTupleScheme();
      }
    }

    private static class userHasAccess_resultTupleScheme extends org.apache.thrift.scheme.TupleScheme<userHasAccess_result> {

      @Override
      public void write(org.apache.thrift.protocol.TProtocol prot, userHasAccess_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet optionals = new java.util.BitSet();
        if (struct.isSetSuccess()) {
          optionals.set(0);
        }
        if (struct.isSetSre()) {
          optionals.set(1);
        }
        oprot.writeBitSet(optionals, 2);
        if (struct.isSetSuccess()) {
          oprot.writeBool(struct.success);
        }
        if (struct.isSetSre()) {
          struct.sre.write(oprot);
        }
      }

      @Override
      public void read(org.apache.thrift.protocol.TProtocol prot, userHasAccess_result struct) throws org.apache.thrift.TException {
        org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
        java.util.BitSet incoming = iprot.readBitSet(2);
        if (incoming.get(0)) {
          struct.success = iprot.readBool();
          struct.setSuccessIsSet(true);
        }
        if (incoming.get(1)) {
          struct.sre = new org.apache.airavata.sharing.registry.models.SharingRegistryException();
          struct.sre.read(iprot);
          struct.setSreIsSet(true);
        }
      }
    }

    private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
      return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
    }
  }

}
