def do_fetch(self, cmd):
        if self.state != "selected":
            raise No("Client must be in the selected state")

        # If self.mbox is None then this mailbox was deleted while this user
        # had it selected. In that case we disconnect the user and let them
        # reconnect and relearn mailbox state.
        #
        if self.mbox is None:
            self.unceremonious_bye("Your selected mailbox no longer exists")
            return

        # If there are commands pending in the queue this gets put on the queue
        # waiting for those to be finished before processing.
        #
        if not self.process_or_queue(cmd):
            return False

        # If this client has pending EXPUNGE messages then we return a tagged
        # No response.. the client should see this and do a NOOP or such and
        # receive the pending expunges. Unless this is a UID command. It is
        # okay to send pending expunges during the operations of a UID FETCH.
        #
        if len(self.pending_expunges) > 0:
            if cmd.uid_command:
                self.send_pending_expunges()
            else:
                # If a client continues to pound us asking for FETCH's when
                # there are pending EXPUNGE's give them the finger by forcing
                # them to disconnect. It is obvious watching Mail.app that it
                # will not give up when given a No so we punt this connection
                # of theirs. They should reconnect and learn the error of their
                # ways.
                #
                self.fetch_while_pending_count += 1
                if self.fetch_while_pending_count > 10:
                    self.unceremonious_bye("You have pending EXPUNGEs.")
                    return
                else:
                    raise No("There are pending EXPUNGEs.")

        self.fetch_while_pending_count = 0
        success = False
        count = 0
        while not success:
            try:
                count += 1
                seq_changed = self._fetch_internal(cmd, count)
                break
            except MailboxInconsistency, e:
                self.server.msg_cache.clear_mbox(self.mbox.name)
                self.log.warn("do_fetch: %s, "
                              "Try %d" % (str(e),count))
                if count > 5:
                    raise e

        # If the fetch caused sequences to change then we need to make the
        # resync non-optional so that we will send FETCH messages to the other
        # clients listening to this mailbox.
        #
        if seq_changed:
            self.mbox.resync(optional = False)

        # If 'needs_continuation' is True then we have actually only partially
        # processed this command. We push this command on to the end of the
        # command_queue for this folder. It will get picked off and processed
        # later through the event loop. The command itself keeps track of where
        # it is in terms of processing.
        #
        if cmd.needs_continuation:
            self.mbox.command_queue.append((self, cmd))
            return False

        return None

    ##################################################################
    #
Fetch data from the messages indicated in the command.
dataset/ETHPy150Open scanner/asimap/asimap/client.py/Authenticated.do_fetch