#
# Autogenerated by Thrift Compiler (0.18.1)
#
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
#
#  options string: py
#

from thrift.Thrift import TType, TMessageType, TFrozenDict, TException, TApplicationException
from thrift.protocol.TProtocol import TProtocolException
from thrift.TRecursive import fix_spec

import sys
import airavata.base.api.BaseAPI
import logging
from .ttypes import *
from thrift.Thrift import TProcessor
from thrift.transport import TTransport
all_structs = []


class Iface(airavata.base.api.BaseAPI.Iface):
    def setUpGateway(self, authzToken, gateway):
        """
        Parameters:
         - authzToken
         - gateway

        """
        pass

    def isUsernameAvailable(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        pass

    def registerUser(self, authzToken, username, emailAddress, firstName, lastName, newPassword):
        """
        Parameters:
         - authzToken
         - username
         - emailAddress
         - firstName
         - lastName
         - newPassword

        """
        pass

    def enableUser(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        pass

    def isUserEnabled(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        pass

    def isUserExist(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        pass

    def getUser(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        pass

    def getUsers(self, authzToken, offset, limit, search):
        """
        Parameters:
         - authzToken
         - offset
         - limit
         - search

        """
        pass

    def resetUserPassword(self, authzToken, username, newPassword):
        """
        Parameters:
         - authzToken
         - username
         - newPassword

        """
        pass

    def findUsers(self, authzToken, email, userId):
        """
        Parameters:
         - authzToken
         - email
         - userId

        """
        pass

    def updateUserProfile(self, authzToken, userDetails):
        """
        Parameters:
         - authzToken
         - userDetails

        """
        pass

    def deleteUser(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        pass

    def addRoleToUser(self, authzToken, username, roleName):
        """
        Parameters:
         - authzToken
         - username
         - roleName

        """
        pass

    def removeRoleFromUser(self, authzToken, username, roleName):
        """
        Parameters:
         - authzToken
         - username
         - roleName

        """
        pass

    def getUsersWithRole(self, authzToken, roleName):
        """
        Parameters:
         - authzToken
         - roleName

        """
        pass


class Client(airavata.base.api.BaseAPI.Client, Iface):
    def __init__(self, iprot, oprot=None):
        airavata.base.api.BaseAPI.Client.__init__(self, iprot, oprot)

    def setUpGateway(self, authzToken, gateway):
        """
        Parameters:
         - authzToken
         - gateway

        """
        self.send_setUpGateway(authzToken, gateway)
        return self.recv_setUpGateway()

    def send_setUpGateway(self, authzToken, gateway):
        self._oprot.writeMessageBegin('setUpGateway', TMessageType.CALL, self._seqid)
        args = setUpGateway_args()
        args.authzToken = authzToken
        args.gateway = gateway
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_setUpGateway(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = setUpGateway_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "setUpGateway failed: unknown result")

    def isUsernameAvailable(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        self.send_isUsernameAvailable(authzToken, username)
        return self.recv_isUsernameAvailable()

    def send_isUsernameAvailable(self, authzToken, username):
        self._oprot.writeMessageBegin('isUsernameAvailable', TMessageType.CALL, self._seqid)
        args = isUsernameAvailable_args()
        args.authzToken = authzToken
        args.username = username
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_isUsernameAvailable(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = isUsernameAvailable_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "isUsernameAvailable failed: unknown result")

    def registerUser(self, authzToken, username, emailAddress, firstName, lastName, newPassword):
        """
        Parameters:
         - authzToken
         - username
         - emailAddress
         - firstName
         - lastName
         - newPassword

        """
        self.send_registerUser(authzToken, username, emailAddress, firstName, lastName, newPassword)
        return self.recv_registerUser()

    def send_registerUser(self, authzToken, username, emailAddress, firstName, lastName, newPassword):
        self._oprot.writeMessageBegin('registerUser', TMessageType.CALL, self._seqid)
        args = registerUser_args()
        args.authzToken = authzToken
        args.username = username
        args.emailAddress = emailAddress
        args.firstName = firstName
        args.lastName = lastName
        args.newPassword = newPassword
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_registerUser(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = registerUser_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "registerUser failed: unknown result")

    def enableUser(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        self.send_enableUser(authzToken, username)
        return self.recv_enableUser()

    def send_enableUser(self, authzToken, username):
        self._oprot.writeMessageBegin('enableUser', TMessageType.CALL, self._seqid)
        args = enableUser_args()
        args.authzToken = authzToken
        args.username = username
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_enableUser(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = enableUser_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "enableUser failed: unknown result")

    def isUserEnabled(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        self.send_isUserEnabled(authzToken, username)
        return self.recv_isUserEnabled()

    def send_isUserEnabled(self, authzToken, username):
        self._oprot.writeMessageBegin('isUserEnabled', TMessageType.CALL, self._seqid)
        args = isUserEnabled_args()
        args.authzToken = authzToken
        args.username = username
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_isUserEnabled(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = isUserEnabled_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "isUserEnabled failed: unknown result")

    def isUserExist(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        self.send_isUserExist(authzToken, username)
        return self.recv_isUserExist()

    def send_isUserExist(self, authzToken, username):
        self._oprot.writeMessageBegin('isUserExist', TMessageType.CALL, self._seqid)
        args = isUserExist_args()
        args.authzToken = authzToken
        args.username = username
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_isUserExist(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = isUserExist_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "isUserExist failed: unknown result")

    def getUser(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        self.send_getUser(authzToken, username)
        return self.recv_getUser()

    def send_getUser(self, authzToken, username):
        self._oprot.writeMessageBegin('getUser', TMessageType.CALL, self._seqid)
        args = getUser_args()
        args.authzToken = authzToken
        args.username = username
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getUser(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getUser_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getUser failed: unknown result")

    def getUsers(self, authzToken, offset, limit, search):
        """
        Parameters:
         - authzToken
         - offset
         - limit
         - search

        """
        self.send_getUsers(authzToken, offset, limit, search)
        return self.recv_getUsers()

    def send_getUsers(self, authzToken, offset, limit, search):
        self._oprot.writeMessageBegin('getUsers', TMessageType.CALL, self._seqid)
        args = getUsers_args()
        args.authzToken = authzToken
        args.offset = offset
        args.limit = limit
        args.search = search
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getUsers(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getUsers_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getUsers failed: unknown result")

    def resetUserPassword(self, authzToken, username, newPassword):
        """
        Parameters:
         - authzToken
         - username
         - newPassword

        """
        self.send_resetUserPassword(authzToken, username, newPassword)
        return self.recv_resetUserPassword()

    def send_resetUserPassword(self, authzToken, username, newPassword):
        self._oprot.writeMessageBegin('resetUserPassword', TMessageType.CALL, self._seqid)
        args = resetUserPassword_args()
        args.authzToken = authzToken
        args.username = username
        args.newPassword = newPassword
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_resetUserPassword(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = resetUserPassword_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "resetUserPassword failed: unknown result")

    def findUsers(self, authzToken, email, userId):
        """
        Parameters:
         - authzToken
         - email
         - userId

        """
        self.send_findUsers(authzToken, email, userId)
        return self.recv_findUsers()

    def send_findUsers(self, authzToken, email, userId):
        self._oprot.writeMessageBegin('findUsers', TMessageType.CALL, self._seqid)
        args = findUsers_args()
        args.authzToken = authzToken
        args.email = email
        args.userId = userId
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_findUsers(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = findUsers_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "findUsers failed: unknown result")

    def updateUserProfile(self, authzToken, userDetails):
        """
        Parameters:
         - authzToken
         - userDetails

        """
        self.send_updateUserProfile(authzToken, userDetails)
        self.recv_updateUserProfile()

    def send_updateUserProfile(self, authzToken, userDetails):
        self._oprot.writeMessageBegin('updateUserProfile', TMessageType.CALL, self._seqid)
        args = updateUserProfile_args()
        args.authzToken = authzToken
        args.userDetails = userDetails
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_updateUserProfile(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = updateUserProfile_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        return

    def deleteUser(self, authzToken, username):
        """
        Parameters:
         - authzToken
         - username

        """
        self.send_deleteUser(authzToken, username)
        return self.recv_deleteUser()

    def send_deleteUser(self, authzToken, username):
        self._oprot.writeMessageBegin('deleteUser', TMessageType.CALL, self._seqid)
        args = deleteUser_args()
        args.authzToken = authzToken
        args.username = username
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_deleteUser(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = deleteUser_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "deleteUser failed: unknown result")

    def addRoleToUser(self, authzToken, username, roleName):
        """
        Parameters:
         - authzToken
         - username
         - roleName

        """
        self.send_addRoleToUser(authzToken, username, roleName)
        return self.recv_addRoleToUser()

    def send_addRoleToUser(self, authzToken, username, roleName):
        self._oprot.writeMessageBegin('addRoleToUser', TMessageType.CALL, self._seqid)
        args = addRoleToUser_args()
        args.authzToken = authzToken
        args.username = username
        args.roleName = roleName
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_addRoleToUser(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = addRoleToUser_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "addRoleToUser failed: unknown result")

    def removeRoleFromUser(self, authzToken, username, roleName):
        """
        Parameters:
         - authzToken
         - username
         - roleName

        """
        self.send_removeRoleFromUser(authzToken, username, roleName)
        return self.recv_removeRoleFromUser()

    def send_removeRoleFromUser(self, authzToken, username, roleName):
        self._oprot.writeMessageBegin('removeRoleFromUser', TMessageType.CALL, self._seqid)
        args = removeRoleFromUser_args()
        args.authzToken = authzToken
        args.username = username
        args.roleName = roleName
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_removeRoleFromUser(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = removeRoleFromUser_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "removeRoleFromUser failed: unknown result")

    def getUsersWithRole(self, authzToken, roleName):
        """
        Parameters:
         - authzToken
         - roleName

        """
        self.send_getUsersWithRole(authzToken, roleName)
        return self.recv_getUsersWithRole()

    def send_getUsersWithRole(self, authzToken, roleName):
        self._oprot.writeMessageBegin('getUsersWithRole', TMessageType.CALL, self._seqid)
        args = getUsersWithRole_args()
        args.authzToken = authzToken
        args.roleName = roleName
        args.write(self._oprot)
        self._oprot.writeMessageEnd()
        self._oprot.trans.flush()

    def recv_getUsersWithRole(self):
        iprot = self._iprot
        (fname, mtype, rseqid) = iprot.readMessageBegin()
        if mtype == TMessageType.EXCEPTION:
            x = TApplicationException()
            x.read(iprot)
            iprot.readMessageEnd()
            raise x
        result = getUsersWithRole_result()
        result.read(iprot)
        iprot.readMessageEnd()
        if result.success is not None:
            return result.success
        if result.Idse is not None:
            raise result.Idse
        if result.ae is not None:
            raise result.ae
        raise TApplicationException(TApplicationException.MISSING_RESULT, "getUsersWithRole failed: unknown result")


class Processor(airavata.base.api.BaseAPI.Processor, Iface, TProcessor):
    def __init__(self, handler):
        airavata.base.api.BaseAPI.Processor.__init__(self, handler)
        self._processMap["setUpGateway"] = Processor.process_setUpGateway
        self._processMap["isUsernameAvailable"] = Processor.process_isUsernameAvailable
        self._processMap["registerUser"] = Processor.process_registerUser
        self._processMap["enableUser"] = Processor.process_enableUser
        self._processMap["isUserEnabled"] = Processor.process_isUserEnabled
        self._processMap["isUserExist"] = Processor.process_isUserExist
        self._processMap["getUser"] = Processor.process_getUser
        self._processMap["getUsers"] = Processor.process_getUsers
        self._processMap["resetUserPassword"] = Processor.process_resetUserPassword
        self._processMap["findUsers"] = Processor.process_findUsers
        self._processMap["updateUserProfile"] = Processor.process_updateUserProfile
        self._processMap["deleteUser"] = Processor.process_deleteUser
        self._processMap["addRoleToUser"] = Processor.process_addRoleToUser
        self._processMap["removeRoleFromUser"] = Processor.process_removeRoleFromUser
        self._processMap["getUsersWithRole"] = Processor.process_getUsersWithRole
        self._on_message_begin = None

    def on_message_begin(self, func):
        self._on_message_begin = func

    def process(self, iprot, oprot):
        (name, type, seqid) = iprot.readMessageBegin()
        if self._on_message_begin:
            self._on_message_begin(name, type, seqid)
        if name not in self._processMap:
            iprot.skip(TType.STRUCT)
            iprot.readMessageEnd()
            x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name))
            oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid)
            x.write(oprot)
            oprot.writeMessageEnd()
            oprot.trans.flush()
            return
        else:
            self._processMap[name](self, seqid, iprot, oprot)
        return True

    def process_setUpGateway(self, seqid, iprot, oprot):
        args = setUpGateway_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = setUpGateway_result()
        try:
            result.success = self._handler.setUpGateway(args.authzToken, args.gateway)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("setUpGateway", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_isUsernameAvailable(self, seqid, iprot, oprot):
        args = isUsernameAvailable_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = isUsernameAvailable_result()
        try:
            result.success = self._handler.isUsernameAvailable(args.authzToken, args.username)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("isUsernameAvailable", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_registerUser(self, seqid, iprot, oprot):
        args = registerUser_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = registerUser_result()
        try:
            result.success = self._handler.registerUser(args.authzToken, args.username, args.emailAddress, args.firstName, args.lastName, args.newPassword)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("registerUser", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_enableUser(self, seqid, iprot, oprot):
        args = enableUser_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = enableUser_result()
        try:
            result.success = self._handler.enableUser(args.authzToken, args.username)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("enableUser", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_isUserEnabled(self, seqid, iprot, oprot):
        args = isUserEnabled_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = isUserEnabled_result()
        try:
            result.success = self._handler.isUserEnabled(args.authzToken, args.username)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("isUserEnabled", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_isUserExist(self, seqid, iprot, oprot):
        args = isUserExist_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = isUserExist_result()
        try:
            result.success = self._handler.isUserExist(args.authzToken, args.username)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("isUserExist", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getUser(self, seqid, iprot, oprot):
        args = getUser_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getUser_result()
        try:
            result.success = self._handler.getUser(args.authzToken, args.username)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getUser", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getUsers(self, seqid, iprot, oprot):
        args = getUsers_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getUsers_result()
        try:
            result.success = self._handler.getUsers(args.authzToken, args.offset, args.limit, args.search)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getUsers", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_resetUserPassword(self, seqid, iprot, oprot):
        args = resetUserPassword_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = resetUserPassword_result()
        try:
            result.success = self._handler.resetUserPassword(args.authzToken, args.username, args.newPassword)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("resetUserPassword", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_findUsers(self, seqid, iprot, oprot):
        args = findUsers_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = findUsers_result()
        try:
            result.success = self._handler.findUsers(args.authzToken, args.email, args.userId)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("findUsers", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_updateUserProfile(self, seqid, iprot, oprot):
        args = updateUserProfile_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = updateUserProfile_result()
        try:
            self._handler.updateUserProfile(args.authzToken, args.userDetails)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("updateUserProfile", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_deleteUser(self, seqid, iprot, oprot):
        args = deleteUser_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = deleteUser_result()
        try:
            result.success = self._handler.deleteUser(args.authzToken, args.username)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("deleteUser", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_addRoleToUser(self, seqid, iprot, oprot):
        args = addRoleToUser_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = addRoleToUser_result()
        try:
            result.success = self._handler.addRoleToUser(args.authzToken, args.username, args.roleName)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("addRoleToUser", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_removeRoleFromUser(self, seqid, iprot, oprot):
        args = removeRoleFromUser_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = removeRoleFromUser_result()
        try:
            result.success = self._handler.removeRoleFromUser(args.authzToken, args.username, args.roleName)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("removeRoleFromUser", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

    def process_getUsersWithRole(self, seqid, iprot, oprot):
        args = getUsersWithRole_args()
        args.read(iprot)
        iprot.readMessageEnd()
        result = getUsersWithRole_result()
        try:
            result.success = self._handler.getUsersWithRole(args.authzToken, args.roleName)
            msg_type = TMessageType.REPLY
        except TTransport.TTransportException:
            raise
        except airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException as Idse:
            msg_type = TMessageType.REPLY
            result.Idse = Idse
        except airavata.api.error.ttypes.AuthorizationException as ae:
            msg_type = TMessageType.REPLY
            result.ae = ae
        except TApplicationException as ex:
            logging.exception('TApplication exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = ex
        except Exception:
            logging.exception('Unexpected exception in handler')
            msg_type = TMessageType.EXCEPTION
            result = TApplicationException(TApplicationException.INTERNAL_ERROR, 'Internal error')
        oprot.writeMessageBegin("getUsersWithRole", msg_type, seqid)
        result.write(oprot)
        oprot.writeMessageEnd()
        oprot.trans.flush()

# HELPER FUNCTIONS AND STRUCTURES


class setUpGateway_args(object):
    """
    Attributes:
     - authzToken
     - gateway

    """


    def __init__(self, authzToken=None, gateway=None,):
        self.authzToken = authzToken
        self.gateway = gateway

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.gateway = airavata.model.workspace.ttypes.Gateway()
                    self.gateway.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('setUpGateway_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.gateway is not None:
            oprot.writeFieldBegin('gateway', TType.STRUCT, 2)
            self.gateway.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.gateway is None:
            raise TProtocolException(message='Required field gateway is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(setUpGateway_args)
setUpGateway_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRUCT, 'gateway', [airavata.model.workspace.ttypes.Gateway, None], None, ),  # 2
)


class setUpGateway_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = airavata.model.workspace.ttypes.Gateway()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('setUpGateway_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(setUpGateway_result)
setUpGateway_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [airavata.model.workspace.ttypes.Gateway, None], None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class isUsernameAvailable_args(object):
    """
    Attributes:
     - authzToken
     - username

    """


    def __init__(self, authzToken=None, username=None,):
        self.authzToken = authzToken
        self.username = username

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isUsernameAvailable_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(isUsernameAvailable_args)
isUsernameAvailable_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
)


class isUsernameAvailable_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isUsernameAvailable_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(isUsernameAvailable_result)
isUsernameAvailable_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class registerUser_args(object):
    """
    Attributes:
     - authzToken
     - username
     - emailAddress
     - firstName
     - lastName
     - newPassword

    """


    def __init__(self, authzToken=None, username=None, emailAddress=None, firstName=None, lastName=None, newPassword=None,):
        self.authzToken = authzToken
        self.username = username
        self.emailAddress = emailAddress
        self.firstName = firstName
        self.lastName = lastName
        self.newPassword = newPassword

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.emailAddress = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRING:
                    self.firstName = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 5:
                if ftype == TType.STRING:
                    self.lastName = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 6:
                if ftype == TType.STRING:
                    self.newPassword = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('registerUser_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        if self.emailAddress is not None:
            oprot.writeFieldBegin('emailAddress', TType.STRING, 3)
            oprot.writeString(self.emailAddress.encode('utf-8') if sys.version_info[0] == 2 else self.emailAddress)
            oprot.writeFieldEnd()
        if self.firstName is not None:
            oprot.writeFieldBegin('firstName', TType.STRING, 4)
            oprot.writeString(self.firstName.encode('utf-8') if sys.version_info[0] == 2 else self.firstName)
            oprot.writeFieldEnd()
        if self.lastName is not None:
            oprot.writeFieldBegin('lastName', TType.STRING, 5)
            oprot.writeString(self.lastName.encode('utf-8') if sys.version_info[0] == 2 else self.lastName)
            oprot.writeFieldEnd()
        if self.newPassword is not None:
            oprot.writeFieldBegin('newPassword', TType.STRING, 6)
            oprot.writeString(self.newPassword.encode('utf-8') if sys.version_info[0] == 2 else self.newPassword)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        if self.emailAddress is None:
            raise TProtocolException(message='Required field emailAddress is unset!')
        if self.firstName is None:
            raise TProtocolException(message='Required field firstName is unset!')
        if self.lastName is None:
            raise TProtocolException(message='Required field lastName is unset!')
        if self.newPassword is None:
            raise TProtocolException(message='Required field newPassword is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(registerUser_args)
registerUser_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'emailAddress', 'UTF8', None, ),  # 3
    (4, TType.STRING, 'firstName', 'UTF8', None, ),  # 4
    (5, TType.STRING, 'lastName', 'UTF8', None, ),  # 5
    (6, TType.STRING, 'newPassword', 'UTF8', None, ),  # 6
)


class registerUser_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('registerUser_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(registerUser_result)
registerUser_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class enableUser_args(object):
    """
    Attributes:
     - authzToken
     - username

    """


    def __init__(self, authzToken=None, username=None,):
        self.authzToken = authzToken
        self.username = username

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('enableUser_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(enableUser_args)
enableUser_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
)


class enableUser_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('enableUser_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(enableUser_result)
enableUser_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class isUserEnabled_args(object):
    """
    Attributes:
     - authzToken
     - username

    """


    def __init__(self, authzToken=None, username=None,):
        self.authzToken = authzToken
        self.username = username

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isUserEnabled_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(isUserEnabled_args)
isUserEnabled_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
)


class isUserEnabled_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isUserEnabled_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(isUserEnabled_result)
isUserEnabled_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class isUserExist_args(object):
    """
    Attributes:
     - authzToken
     - username

    """


    def __init__(self, authzToken=None, username=None,):
        self.authzToken = authzToken
        self.username = username

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isUserExist_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(isUserExist_args)
isUserExist_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
)


class isUserExist_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('isUserExist_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(isUserExist_result)
isUserExist_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class getUser_args(object):
    """
    Attributes:
     - authzToken
     - username

    """


    def __init__(self, authzToken=None, username=None,):
        self.authzToken = authzToken
        self.username = username

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getUser_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(getUser_args)
getUser_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
)


class getUser_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.STRUCT:
                    self.success = airavata.model.user.ttypes.UserProfile()
                    self.success.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getUser_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.STRUCT, 0)
            self.success.write(oprot)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(getUser_result)
getUser_result.thrift_spec = (
    (0, TType.STRUCT, 'success', [airavata.model.user.ttypes.UserProfile, None], None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class getUsers_args(object):
    """
    Attributes:
     - authzToken
     - offset
     - limit
     - search

    """


    def __init__(self, authzToken=None, offset=None, limit=None, search=None,):
        self.authzToken = authzToken
        self.offset = offset
        self.limit = limit
        self.search = search

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.I32:
                    self.offset = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.I32:
                    self.limit = iprot.readI32()
                else:
                    iprot.skip(ftype)
            elif fid == 4:
                if ftype == TType.STRING:
                    self.search = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getUsers_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.offset is not None:
            oprot.writeFieldBegin('offset', TType.I32, 2)
            oprot.writeI32(self.offset)
            oprot.writeFieldEnd()
        if self.limit is not None:
            oprot.writeFieldBegin('limit', TType.I32, 3)
            oprot.writeI32(self.limit)
            oprot.writeFieldEnd()
        if self.search is not None:
            oprot.writeFieldBegin('search', TType.STRING, 4)
            oprot.writeString(self.search.encode('utf-8') if sys.version_info[0] == 2 else self.search)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.offset is None:
            raise TProtocolException(message='Required field offset is unset!')
        if self.limit is None:
            raise TProtocolException(message='Required field limit is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(getUsers_args)
getUsers_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.I32, 'offset', None, None, ),  # 2
    (3, TType.I32, 'limit', None, None, ),  # 3
    (4, TType.STRING, 'search', 'UTF8', None, ),  # 4
)


class getUsers_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype3, _size0) = iprot.readListBegin()
                    for _i4 in range(_size0):
                        _elem5 = airavata.model.user.ttypes.UserProfile()
                        _elem5.read(iprot)
                        self.success.append(_elem5)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getUsers_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter6 in self.success:
                iter6.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(getUsers_result)
getUsers_result.thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT, [airavata.model.user.ttypes.UserProfile, None], False), None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class resetUserPassword_args(object):
    """
    Attributes:
     - authzToken
     - username
     - newPassword

    """


    def __init__(self, authzToken=None, username=None, newPassword=None,):
        self.authzToken = authzToken
        self.username = username
        self.newPassword = newPassword

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.newPassword = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('resetUserPassword_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        if self.newPassword is not None:
            oprot.writeFieldBegin('newPassword', TType.STRING, 3)
            oprot.writeString(self.newPassword.encode('utf-8') if sys.version_info[0] == 2 else self.newPassword)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        if self.newPassword is None:
            raise TProtocolException(message='Required field newPassword is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(resetUserPassword_args)
resetUserPassword_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'newPassword', 'UTF8', None, ),  # 3
)


class resetUserPassword_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('resetUserPassword_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(resetUserPassword_result)
resetUserPassword_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class findUsers_args(object):
    """
    Attributes:
     - authzToken
     - email
     - userId

    """


    def __init__(self, authzToken=None, email=None, userId=None,):
        self.authzToken = authzToken
        self.email = email
        self.userId = userId

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.email = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.userId = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('findUsers_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.email is not None:
            oprot.writeFieldBegin('email', TType.STRING, 2)
            oprot.writeString(self.email.encode('utf-8') if sys.version_info[0] == 2 else self.email)
            oprot.writeFieldEnd()
        if self.userId is not None:
            oprot.writeFieldBegin('userId', TType.STRING, 3)
            oprot.writeString(self.userId.encode('utf-8') if sys.version_info[0] == 2 else self.userId)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.email is None:
            raise TProtocolException(message='Required field email is unset!')
        if self.userId is None:
            raise TProtocolException(message='Required field userId is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(findUsers_args)
findUsers_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'email', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'userId', 'UTF8', None, ),  # 3
)


class findUsers_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype10, _size7) = iprot.readListBegin()
                    for _i11 in range(_size7):
                        _elem12 = airavata.model.user.ttypes.UserProfile()
                        _elem12.read(iprot)
                        self.success.append(_elem12)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('findUsers_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter13 in self.success:
                iter13.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(findUsers_result)
findUsers_result.thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT, [airavata.model.user.ttypes.UserProfile, None], False), None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class updateUserProfile_args(object):
    """
    Attributes:
     - authzToken
     - userDetails

    """


    def __init__(self, authzToken=None, userDetails=None,):
        self.authzToken = authzToken
        self.userDetails = userDetails

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.userDetails = airavata.model.user.ttypes.UserProfile()
                    self.userDetails.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('updateUserProfile_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.userDetails is not None:
            oprot.writeFieldBegin('userDetails', TType.STRUCT, 2)
            self.userDetails.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.userDetails is None:
            raise TProtocolException(message='Required field userDetails is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(updateUserProfile_args)
updateUserProfile_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRUCT, 'userDetails', [airavata.model.user.ttypes.UserProfile, None], None, ),  # 2
)


class updateUserProfile_result(object):
    """
    Attributes:
     - Idse
     - ae

    """


    def __init__(self, Idse=None, ae=None,):
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('updateUserProfile_result')
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(updateUserProfile_result)
updateUserProfile_result.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class deleteUser_args(object):
    """
    Attributes:
     - authzToken
     - username

    """


    def __init__(self, authzToken=None, username=None,):
        self.authzToken = authzToken
        self.username = username

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('deleteUser_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(deleteUser_args)
deleteUser_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
)


class deleteUser_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('deleteUser_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(deleteUser_result)
deleteUser_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class addRoleToUser_args(object):
    """
    Attributes:
     - authzToken
     - username
     - roleName

    """


    def __init__(self, authzToken=None, username=None, roleName=None,):
        self.authzToken = authzToken
        self.username = username
        self.roleName = roleName

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.roleName = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('addRoleToUser_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        if self.roleName is not None:
            oprot.writeFieldBegin('roleName', TType.STRING, 3)
            oprot.writeString(self.roleName.encode('utf-8') if sys.version_info[0] == 2 else self.roleName)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        if self.roleName is None:
            raise TProtocolException(message='Required field roleName is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(addRoleToUser_args)
addRoleToUser_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'roleName', 'UTF8', None, ),  # 3
)


class addRoleToUser_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('addRoleToUser_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(addRoleToUser_result)
addRoleToUser_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class removeRoleFromUser_args(object):
    """
    Attributes:
     - authzToken
     - username
     - roleName

    """


    def __init__(self, authzToken=None, username=None, roleName=None,):
        self.authzToken = authzToken
        self.username = username
        self.roleName = roleName

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.username = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            elif fid == 3:
                if ftype == TType.STRING:
                    self.roleName = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('removeRoleFromUser_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.username is not None:
            oprot.writeFieldBegin('username', TType.STRING, 2)
            oprot.writeString(self.username.encode('utf-8') if sys.version_info[0] == 2 else self.username)
            oprot.writeFieldEnd()
        if self.roleName is not None:
            oprot.writeFieldBegin('roleName', TType.STRING, 3)
            oprot.writeString(self.roleName.encode('utf-8') if sys.version_info[0] == 2 else self.roleName)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.username is None:
            raise TProtocolException(message='Required field username is unset!')
        if self.roleName is None:
            raise TProtocolException(message='Required field roleName is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(removeRoleFromUser_args)
removeRoleFromUser_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'username', 'UTF8', None, ),  # 2
    (3, TType.STRING, 'roleName', 'UTF8', None, ),  # 3
)


class removeRoleFromUser_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.BOOL:
                    self.success = iprot.readBool()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('removeRoleFromUser_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.BOOL, 0)
            oprot.writeBool(self.success)
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(removeRoleFromUser_result)
removeRoleFromUser_result.thrift_spec = (
    (0, TType.BOOL, 'success', None, None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)


class getUsersWithRole_args(object):
    """
    Attributes:
     - authzToken
     - roleName

    """


    def __init__(self, authzToken=None, roleName=None,):
        self.authzToken = authzToken
        self.roleName = roleName

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 1:
                if ftype == TType.STRUCT:
                    self.authzToken = airavata.model.security.ttypes.AuthzToken()
                    self.authzToken.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRING:
                    self.roleName = iprot.readString().decode('utf-8', errors='replace') if sys.version_info[0] == 2 else iprot.readString()
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getUsersWithRole_args')
        if self.authzToken is not None:
            oprot.writeFieldBegin('authzToken', TType.STRUCT, 1)
            self.authzToken.write(oprot)
            oprot.writeFieldEnd()
        if self.roleName is not None:
            oprot.writeFieldBegin('roleName', TType.STRING, 2)
            oprot.writeString(self.roleName.encode('utf-8') if sys.version_info[0] == 2 else self.roleName)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        if self.authzToken is None:
            raise TProtocolException(message='Required field authzToken is unset!')
        if self.roleName is None:
            raise TProtocolException(message='Required field roleName is unset!')
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(getUsersWithRole_args)
getUsersWithRole_args.thrift_spec = (
    None,  # 0
    (1, TType.STRUCT, 'authzToken', [airavata.model.security.ttypes.AuthzToken, None], None, ),  # 1
    (2, TType.STRING, 'roleName', 'UTF8', None, ),  # 2
)


class getUsersWithRole_result(object):
    """
    Attributes:
     - success
     - Idse
     - ae

    """


    def __init__(self, success=None, Idse=None, ae=None,):
        self.success = success
        self.Idse = Idse
        self.ae = ae

    def read(self, iprot):
        if iprot._fast_decode is not None and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None:
            iprot._fast_decode(self, iprot, [self.__class__, self.thrift_spec])
            return
        iprot.readStructBegin()
        while True:
            (fname, ftype, fid) = iprot.readFieldBegin()
            if ftype == TType.STOP:
                break
            if fid == 0:
                if ftype == TType.LIST:
                    self.success = []
                    (_etype17, _size14) = iprot.readListBegin()
                    for _i18 in range(_size14):
                        _elem19 = airavata.model.user.ttypes.UserProfile()
                        _elem19.read(iprot)
                        self.success.append(_elem19)
                    iprot.readListEnd()
                else:
                    iprot.skip(ftype)
            elif fid == 1:
                if ftype == TType.STRUCT:
                    self.Idse = airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException.read(iprot)
                else:
                    iprot.skip(ftype)
            elif fid == 2:
                if ftype == TType.STRUCT:
                    self.ae = airavata.api.error.ttypes.AuthorizationException.read(iprot)
                else:
                    iprot.skip(ftype)
            else:
                iprot.skip(ftype)
            iprot.readFieldEnd()
        iprot.readStructEnd()

    def write(self, oprot):
        if oprot._fast_encode is not None and self.thrift_spec is not None:
            oprot.trans.write(oprot._fast_encode(self, [self.__class__, self.thrift_spec]))
            return
        oprot.writeStructBegin('getUsersWithRole_result')
        if self.success is not None:
            oprot.writeFieldBegin('success', TType.LIST, 0)
            oprot.writeListBegin(TType.STRUCT, len(self.success))
            for iter20 in self.success:
                iter20.write(oprot)
            oprot.writeListEnd()
            oprot.writeFieldEnd()
        if self.Idse is not None:
            oprot.writeFieldBegin('Idse', TType.STRUCT, 1)
            self.Idse.write(oprot)
            oprot.writeFieldEnd()
        if self.ae is not None:
            oprot.writeFieldBegin('ae', TType.STRUCT, 2)
            self.ae.write(oprot)
            oprot.writeFieldEnd()
        oprot.writeFieldStop()
        oprot.writeStructEnd()

    def validate(self):
        return

    def __repr__(self):
        L = ['%s=%r' % (key, value)
             for key, value in self.__dict__.items()]
        return '%s(%s)' % (self.__class__.__name__, ', '.join(L))

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not (self == other)
all_structs.append(getUsersWithRole_result)
getUsersWithRole_result.thrift_spec = (
    (0, TType.LIST, 'success', (TType.STRUCT, [airavata.model.user.ttypes.UserProfile, None], False), None, ),  # 0
    (1, TType.STRUCT, 'Idse', [airavata.service.profile.iam.admin.services.cpi.error.ttypes.IamAdminServicesException, None], None, ),  # 1
    (2, TType.STRUCT, 'ae', [airavata.api.error.ttypes.AuthorizationException, None], None, ),  # 2
)
fix_spec(all_structs)
del all_structs
