High-level IRC buffering system and processor.
        Optional arguments:
        * timeout=None - Time to wait before returning None.
            Defaults to waiting forever.

def recv(self, timeout=None):
        """
        High-level IRC buffering system and processor.
        Optional arguments:
        * timeout=None - Time to wait before returning None.
            Defaults to waiting forever.
        """
        with self.lock:
            if timeout != None:
                if self.readable(timeout) == False:
                    return None
            data = self._raw_recv()
            segments = data.split()

            if segments[1] == 'JOIN':
                who = self._from_(segments[0][1:])
                channel = segments[2][1:]
                if channel not in self.channels:
                    self.stepback(append=False)
                    return 'JOIN', self.join_(channel, process_only=True)
                else:
                    self.channels[channel]['USERS'][who[0]] = \
                    ['', '', '', '', '']
                return 'JOIN', (who, channel)

            elif segments[1] == 'PART':
                who = self._from_(segments[0].replace(':', '', 1))
                channel = segments[2]
                del self.channels[channel]['USERS'][who[0]]
                try:
                    reason = ' '.join(segments[3:]).replace(':', '', 1)
                    return 'PART', (who, channel, reason)
                except IndexError:
                    who = self._from_(segments[0].replace(':', '', 1))
                    return 'PART', (who, channel, '')

            elif segments[1] == 'PRIVMSG':
                who = self._from_(segments[0].replace(':', '', 1))
                msg = ' '.join(segments[3:]).replace(':', '', 1)
                rvalue = 'PRIVMSG', (who, segments[2], msg)

                if msg.find('\001') == 0:
                    rctcp = self.ctcp_decode(msg)
                    return 'CTCP', (rvalue[1][0], rvalue[1][1], rctcp)
                else:
                    return rvalue

            elif segments[1] == 'NOTICE':
                who = self._from_(segments[0].replace(':', '', 1))
                msg = ' '.join(segments[3:]).replace(':', '', 1)
                if msg.find('\001') == 0:
                    msg = self.ctcp_decode(msg)
                    return 'CTCP_REPLY', (who, segments[2], msg)
                return 'NOTICE', (who, segments[2], msg)

            elif segments[1] == 'MODE':
                mode = ' '.join(segments[3:]).replace(':', '', 1)
                who = self._from_(segments[0][1:])
                target = segments[2]
                if target != self.current_nick:
                    self.parse_cmode_string(mode, target)
                    return 'MODE', (who, segments[2], mode)
                else:
                    return 'MODE', (who, mode.replace(':', '', 1))

            elif segments[1] == 'KICK':
                who = self._from_(segments[0].replace(':', '', 1))
                if self.current_nick == segments[3]:
                    del self.channels[segments[2]]
                else:
                    del self.channels[segments[2]]['USERS'][segments[3]]
                reason = ' '.join(segments[4:]).replace(':', '', 1)
                return 'KICK', (who, segments[2], segments[3], reason)

            elif segments[1] == 'INVITE':
                who = self._from_(segments[0].replace(':', '', 1))
                channel = segments[3].replace(':', '', 1)
                return 'INVITE', (who, segments[2], channel)

            elif segments[1] == 'NICK':
                who = self._from_(segments[0].replace(':', '', 1))
                new_nick = ' '.join(segments[2:]).replace(':', '', 1)
                if self.current_nick == who[0]:
                    self.current_nick = new_nick
                for channel in self.channels:
                    if who[0] in self.channels[channel]['USERS']:
                        priv_level = self.channels[channel]['USERS'][who[0]]
                        del self.channels[channel]['USERS'][who[0]]
                        self.channels[channel]['USERS'][new_nick] = priv_level
                return 'NICK', (who, new_nick)

            elif segments[1] == 'TOPIC':
                who = self._from_(segments[0].replace(':', '', 1))
                channel = segments[2]
                topic = ' '.join(segments[3:]).replace(':', '', 1)
                self.channels[channel]['TOPIC'] = topic
                return 'TOPIC', (who, channel, topic)

            elif segments[1] == 'QUIT':
                who = self._from_(segments[0].replace(':', '', 1))
                msg = ' '.join(segments[2:]).replace(':', '', 1)
                for channel in self.channels:
                    if who[0] in self.channels[channel]['USERS']:
                        del self.channels[channel]['USERS'][who[0]]
                return 'QUIT', (who, msg)

            elif segments[1] == '250':
                self.lusers['HIGHESTCONNECTIONS'] = segments[6]
                self.lusers['TOTALCONNECTIONS'] = segments[9][1:]
                return 'LUSERS', self.lusers

            elif segments[1] == '251':
                self.lusers['USERS'] = segments[5]
                self.lusers['INVISIBLE'] = segments[8]
                self.lusers['SERVERS'] = segments[11]
                return 'LUSERS', self.lusers

            elif segments[1] == '252':
                self.lusers['OPERATORS'] = segments[3]
                return 'LUSERS', self.lusers

            elif segments[1] == '253':
                self.lusers['UNKNOWN'] = segments[3]
                return 'LUSERS', self.lusers

            elif segments[1] == '254':
                self.lusers['CHANNELS'] = segments[3]
                return 'LUSERS', self.lusers

            elif segments[1] == '255':
                self.lusers['CLIENTS'] = segments[5]
                self.lusers['LSERVERS'] = segments[8]
                return 'LUSERS', self.lusers

            elif segments[1] == '265':
                self.lusers['LOCALUSERS'] = segments[6]
                self.lusers['LOCALMAX'] = segments[8]
                return 'LUSERS', self.lusers

            elif segments[1] == '266':
                self.lusers['GLOBALUSERS'] = segments[6]
                self.lusers['GLOBALMAX'] = segments[8]
                return 'LUSERS', self.lusers

            elif segments[0] == 'ERROR':
                self.quit()
                return 'ERROR', ' '.join(segments[1:]).replace(':', '', 1)
            else:
                self.stepback(append=False)
                return 'UNKNOWN', self._recv(rm_first=False)