diff -ruN msnlib-2.0/doc/Changelog msnlib-2.1/doc/Changelog
--- msnlib-2.0/doc/Changelog	2003-06-08 19:11:31.000000000 -0300
+++ msnlib-2.1/doc/Changelog	2003-08-25 23:14:35.000000000 -0300
@@ -1,3 +1,21 @@
+25 Aug 03 23.14.08 - Alberto <albertogli@telpin.com.ar>
+ * tag: 2.1
+
+25 Aug 03 14.09.17 - Alberto <albertogli@telpin.com.ar>
+ * msnlib: keep message queues when submitting sbds, to avoid loosing messages
+	when two XFRs happen at the 'same' time
+ * msn: priorize users with sbd for tab completion
+
+25 Aug 03 00.05.22 - Alberto <albertogli@telpin.com.ar>
+ * msn: use email instead of nick for tab completion when nick has spaces
+ * msn: implement tab completion for emails and nicks
+
+04 Aug 03 15.07.53 - Alberto <albertogli@telpin.com.ar>
+ * msn: fix user info to avoid crashing when asking for info on users
+	which are not on our list
+ * msn: some indentation work
+ * msncb: close sbd when deleting a user
+
 08 Jun 03 19.11.18 - Alberto <albertogli@telpin.com.ar>
  * tag: 2.0
 
diff -ruN msnlib-2.0/msn msnlib-2.1/msn
--- msnlib-2.0/msn	2003-06-08 19:13:09.000000000 -0300
+++ msnlib-2.1/msn	2003-08-25 23:13:00.000000000 -0300
@@ -207,11 +207,16 @@
 	out += c.bold + 'User info for ' + email + '\n'
 	out += c.bold + 'Nick:\t\t' + c.normal + u.nick + '\n'
 	out += c.bold + 'Status:\t\t' + c.normal + msnlib.reverse_status[u.status] + '\n'
-	out += c.bold + 'Group:\t\t' + c.normal + m.groups[u.gid] + '\n'
-	if u.realnick: out += c.bold + 'Real Nick:\t' + c.normal + u.realnick + '\n'
-	if u.homep: out += c.bold + 'Home phone:\t' + c.normal + u.homep + '\n'
-	if u.workp: out += c.bold + 'Work phone:\t' + c.normal + u.workp + '\n'
-	if u.mobilep: out += c.bold + 'Mobile phone:\t' + c.normal + u.mobilep + '\n'
+	if u.gid != None:
+		out += c.bold + 'Group:\t\t' + c.normal + m.groups[u.gid] + '\n'
+	if u.realnick:
+		out += c.bold + 'Real Nick:\t' + c.normal + u.realnick + '\n'
+	if u.homep:
+		out += c.bold + 'Home phone:\t' + c.normal + u.homep + '\n'
+	if u.workp:
+		out += c.bold + 'Work phone:\t' + c.normal + u.workp + '\n'
+	if u.mobilep:
+		out += c.bold + 'Mobile phone:\t' + c.normal + u.mobilep + '\n'
 	if u.priv.has_key('typing') and u.priv['typing']:
 		out += c.bold + 'Last typing at:\t' + c.normal
 		out += time.asctime(time.localtime(u.priv['typing'])) + '\n'
@@ -325,6 +330,32 @@
 	else:
 		return None
 
+def matchemail(begin):
+	""""Returns a matching email/nick for the given beginning; it avoids
+	nicks with spaces"""
+	l = len(begin)
+	# first try the ones with sbd
+	for email in m.users.keys():
+		if not m.users[email].sbd:
+			continue
+		nick = m.users[email].nick
+		if ' ' in nick:
+			nick = email
+		if len(nick) >= l and nick[0:l] == begin:
+			return nick
+	# then the nicks
+	for email in m.users.keys():
+		nick = m.users[email].nick
+		if ' ' in nick:
+			continue
+		if len(nick) >= l and nick[0:l] == begin:
+			return nick
+	# and finally the emails
+	for email in m.users.keys():
+		if len(email) >= l and email[0:l] == begin:
+			return email
+	return None
+
 def gname2gid(gname):
 	"Returns a group name according to the given group id"
 	for gid in m.groups.keys():
@@ -496,12 +527,18 @@
 			# we see which one applies according to some messy
 			# logic
 			if email2nick(last_received):
-				mtolrecv = 'm ' + email2nick(last_received) + ' '
+				nick = email2nick(last_received)
+				if ' ' in nick:
+					nick = last_received
+				mtolrecv = 'm ' + nick + ' '
 			else:
 				mtolrecv = None
 
 			if email2nick(last_sent):
-				mtolsent = 'm ' + email2nick(last_sent) + ' '
+				nick = email2nick(last_sent)
+				if ' ' in nick:
+					nick = last_sent
+				mtolsent = 'm ' + nick + ' '
 			else:
 				mtolsent = None
 			
@@ -530,10 +567,21 @@
 						inbuf = inbuf[:-1]
 						beep()
 				# we have something that is neither mtolsent or
-				# mtolrecv, so we just beep
+				# mtolrecv, we try to find a matching
+				# email/nick
 				else:
-					inbuf = inbuf[:-1]
-					beep()
+					p = inbuf.split()
+					if p[0] != 'm' or len(p) != 2:
+						inbuf = inbuf[:-1]
+						beep()
+					else:
+						begin = p[1]
+						email = matchemail(begin)
+						if not email:
+							inbuf = inbuf[:-1]
+							beep()
+						else:
+							inbuf = 'm ' + email + ' '
 			redraw_cli()
 			
 		elif ord(char) == 4:				# EOT
@@ -658,7 +706,9 @@
 		if not params:
 			return 'Your current status is %s' % msnlib.reverse_status[m.status]
 		if not m.change_status(params):
-			return 'Status must be one of: online, away, busy, brb, phone, lunch, invisible or idle'
+			out = 'Status must be one of:\n'
+			out += '\tonline, away, busy, brb, phone, lunch, invisible or idle'
+			return out
 		return 'Status changed to: %s' % params
 		
 	elif cmd == 'q':		# quit
@@ -873,7 +923,8 @@
 			out = ''
 			out += c.bold + 'Info for ' + m.email + '\n'
 			out += c.bold + 'Nick:\t\t' + c.normal + m.nick + '\n'
-			out += c.bold + 'Status:\t\t' + c.normal + msnlib.reverse_status[m.status] + '\n'
+			out += c.bold + 'Status:\t\t' \
+				+ c.normal + msnlib.reverse_status[m.status] + '\n'
 			out += c.bold + 'Home phone:\t' + c.normal + str(m.homep) + '\n'
 			out += c.bold + 'Work phone:\t' + c.normal + str(m.workp) + '\n'
 			out += c.bold + 'Mobile phone:\t' + c.normal + str(m.mobilep) + '\n'
@@ -895,7 +946,8 @@
 		m.sync()
 	
 	elif cmd == 'h':		# show history
-		printl('Incoming Message History (last %d messages)\n' % config['history size'], c.green, 1)
+		printl('Incoming Message History (last %d messages)\n' \
+			% config['history size'], c.green, 1)
 		for i in history_ring:
 			rtime = i[0]
 			email = i[1]
@@ -1143,11 +1195,13 @@
 		email = t[2]
 		nick = urllib.unquote(t[3])
 	if type == 'RL':
-		out = '\r' + c.blue + c.bold + ('%s (%s) ' % (email, nick)) + c.magenta + 'has added you to his contact list\n'
+		out = '\r' + c.blue + c.bold + ('%s (%s) ' % (email, nick)) \
+			+ c.magenta + 'has added you to his contact list\n'
 		printl(out)
 		beep()
 	elif type == 'FL':
-		out = '\r' + c.blue + c.bold + ('%s (%s) ' % (email, nick)) + c.magenta + 'has been added to your contact list\n'
+		out = '\r' + c.blue + c.bold + ('%s (%s) ' % (email, nick)) \
+			+ c.magenta + 'has been added to your contact list\n'
 		printl(out)
 	msncb.cb_add(md, type, tid, params)
 m.cb.add = cb_add
@@ -1158,11 +1212,13 @@
 	if type == 'RL' or type == 'FL':
 		email = t[2]
 	if type == 'RL':
-		out = '\r' + c.blue + c.bold + email + ' ' + c.magenta + 'has removed you from his contact list\n'
+		out = '\r' + c.blue + c.bold + email + ' ' + c.magenta \
+			+ 'has removed you from his contact list\n'
 		printl(out)
 		beep()
 	elif type == 'FL':
-		out = '\r' + c.blue + c.bold + email + ' ' + c.magenta + 'has been removed from your contact list\n'
+		out = '\r' + c.blue + c.bold + email + ' ' + c.magenta \
+			+ 'has been removed from your contact list\n'
 		printl(out)
 	msncb.cb_rem(md, type, tid, params)
 m.cb.rem = cb_rem
@@ -1209,7 +1265,7 @@
 #
 # now the real thing
 #
-printl('* MSN Client (2.0) *\n', c.yellow, 1)
+printl('* MSN Client (2.1) *\n', c.yellow, 1)
 
 # first, the configuration
 printl('Loading config... ', c.green, 1)
diff -ruN msnlib-2.0/msncb.py msnlib-2.1/msncb.py
--- msnlib-2.0/msncb.py	2003-06-07 16:16:22.000000000 -0300
+++ msnlib-2.1/msncb.py	2003-08-25 00:38:14.000000000 -0300
@@ -291,6 +291,8 @@
 		debug('REM: %s removed you' % email)
 	elif type == 'FL':
 		email = t[2]
+		if md.users[email].sbd:
+			md.close(md.users[email].sbd)
 		del(md.users[email])
 		debug('REM: removing %s' % email)
 	else:
@@ -309,6 +311,8 @@
 	lver, gid = t[0:2]
 	for e in md.users.keys():
 		if md.users[e].gid == gid:
+			if md.users[e].sbd:
+				md.close(md.users[e].sbd)
 			del(md.users[e])
 	del(md.groups[gid])
 	debug('RMG: group %s removed' % gid)
diff -ruN msnlib-2.0/msnlib.py msnlib-2.1/msnlib.py
--- msnlib-2.0/msnlib.py	2003-06-08 19:13:17.000000000 -0300
+++ msnlib-2.1/msnlib.py	2003-08-25 23:13:09.000000000 -0300
@@ -14,7 +14,7 @@
 """
 
 # constants
-VERSION = 0x0200
+VERSION = 0x0201
 LOGIN_HOST = 'messenger.hotmail.com'
 LOGIN_PORT = 1863
 
@@ -104,7 +104,8 @@
 	
 	def __repr__(self):
 		return '<sbd: emails:%s state:%s fd:%d endpoint:%s>' % \
-			(str(self.emails), self.state, self.fileno(), self.endpoint)
+			(str(self.emails), self.state, \
+			self.fileno(), self.endpoint)
 	
 	def fileno(self):
 		return self.fd.fileno()
@@ -319,6 +320,8 @@
 		if email not in self.users.keys():
 			self.users[email] = user(email)
 		if self.users[email].sbd and self.users[email].sbd != sbd:
+			# override the sbd, but keep the message queue
+			sbd.msgqueue = self.users[email].sbd.msgqueue[:]
 			self.close(self.users[email].sbd)
 		self.users[email].sbd = sbd
 		return
@@ -568,7 +571,8 @@
 				errno = None
 			
 			if errno:
-				self.cb.err(self, errno, str(tid) + ' ' + str(params))
+				self.cb.err(self, errno, \
+					str(tid) + ' ' + str(params))
 			else:
 				# if we got this far, we have no idea
 				self.cb.unk(self, type, tid, params)
diff -ruN msnlib-2.0/setup.py msnlib-2.1/setup.py
--- msnlib-2.0/setup.py	2003-06-08 19:13:40.000000000 -0300
+++ msnlib-2.1/setup.py	2003-08-25 23:13:18.000000000 -0300
@@ -2,7 +2,7 @@
 from distutils.core import setup
 
 setup(name="msnlib",
-	version="2.0",
+	version="2.1",
 	description="MSN Messenger Library and Client",
 	author="Alberto Bertogli",
 	author_email="albertogli@telpin.com.ar",
