diff --git a/exec/imapservice.js b/exec/imapservice.js
index 2901b334fbff4f228bd94ee048ecc184b816e8b7..a552395072d7aead4ab919a9ecc6c25b243fa20c 100644
--- a/exec/imapservice.js
+++ b/exec/imapservice.js
@@ -54,6 +54,28 @@ function compNumbers(a,b) {
 	return(a-b);
 }
 
+function encode_binary(str)
+{
+	return '{'+str.length+'}\r\n'+str;
+}
+
+function encode_string(str)
+{
+	if(str=='')
+		return('""');
+
+	// An Atom
+	//if(str.search(/[\(\)\{ \x00-\x1F\*\%\"\\\]]*/)==-1)
+	//	return str;
+
+	if(str.search(/[\r\n\x80-\xff]/)==-1) {
+		str=str.replace(/[\\\"]/, "\\$1");
+		return '"'+str+'"';
+	}
+
+	return encode_binary(str);
+}
+
 function send_fetch_response(msgnum, format, uid)
 {
 	var idx=base.get_msg_index(msgnum);
@@ -68,6 +90,7 @@ function send_fetch_response(msgnum, format, uid)
 	var tmp;
 	var sent_flags=false;
 	var seen_changed=false;
+	var envelope;
 
 	function get_header() {
 		if(hdr == undefined) {
@@ -143,6 +166,9 @@ function send_fetch_response(msgnum, format, uid)
 				rfc822.header += "Content-Type: text/plain; charset=IBM437\r\n";
 				rfc822.header += "Content-Transfer-Encoding: 8bit\r\n";
 			}
+
+			// Unwrap headers
+			rfc822.header=rfc822.header.replace(/\s*\r\n\s+/g, " ");
 		}
 		rfc822.header += "\r\n";
 	}
@@ -177,10 +203,56 @@ function send_fetch_response(msgnum, format, uid)
 		}
 	}
 
+	function get_envelope() {
+		function parse_header(header, is_addresses) {
+			var m;
+			var m2;
+			var re;
+
+			re=new RegExp("^"+header+":\\s*(.*?)$","im");
+			m=re.exec(rfc822.header);
+			if(m==null) {
+				return("NIL");
+			}
+			else {
+				if(is_addresses) {
+					if((m2=m[1].match(/^\s*(.*)\s+<([^@]*)@(.*)>\s*$/))!=null) {
+						return '(('+[encode_string(m2[1]), "NIL", encode_string(m2[2]), encode_string(m2[3])].join(" ")+'))';
+					}
+					else if((m2=m[1].match(/^\s*(.*)\s+<([^@]i)>\s*$/))!=null) {
+						return '(('+[encode_string(m2[1]), "NIL", encode_string(m2[2]), NIL].join(" ")+'))';
+					}
+					else
+						return '(('+[encode_string(m[1]), "NIL", "NIL", "NIL"].join(" ")+'))';
+				}
+				else
+					return(encode_string(m[1]));
+			}
+		}
+
+		var m;
+
+		if(envelope==undefined) {
+			get_rfc822_header();
+
+			envelope=[];
+			envelope.push(parse_header("Date", false));
+			envelope.push(parse_header("Subject", false));
+			envelope.push(parse_header("From", true));
+			envelope.push(parse_header("Sender", true));
+			envelope.push(parse_header("Reply-To", true));
+			envelope.push(parse_header("To", true));
+			envelope.push(parse_header("CC", true));
+			envelope.push(parse_header("BCC", true));
+			envelope.push(parse_header("In-Reply-To", false));
+			envelope.push(parse_header("Message-ID", false));
+		}
+	}
+
 	if(base.subnum==65535)
 		resp=inbox_map.offset[msgnum];
 	else
-		resp=idx.offset 
+		resp=idx.offset+1;
 	resp += " FETCH (";
 
 	// Moves flags to the end...
@@ -227,7 +299,7 @@ function send_fetch_response(msgnum, format, uid)
 						}
 					}
 					tmp += "\r\n";
-					resp=resp.substr(0,resp.length-1)+")] {"+tmp.length+"}\r\n"+tmp+" ";
+					resp=resp.substr(0,resp.length-1)+")] "+encode_binary(tmp)+" ";
 					break;
 			}
 			continue;
@@ -256,7 +328,7 @@ function send_fetch_response(msgnum, format, uid)
 				// fall-through
 			case 'BODY.PEEK[TEXT]':
 				get_rfc822_text();
-				resp += format[i].replace(/\.PEEK/,"").toUpperCase()+" {"+rfc822.text.length+"}\r\n"+rfc822.text+" ";
+				resp += format[i].replace(/\.PEEK/,"").toUpperCase()+" "+encode_binary(rfc822.text)+" ";
 				break;
 			case 'BODY[HEADER]':
 			case 'RFC822.HEADER':
@@ -264,7 +336,7 @@ function send_fetch_response(msgnum, format, uid)
 				// fall-through
 			case 'BODY.PEEK[HEADER]':
 				get_rfc822_header();
-				resp += format[i].replace(/\.PEEK/,"").toUpperCase()+" {"+rfc822.header.length+"}\r\n"+rfc822.header+" ";
+				resp += format[i].replace(/\.PEEK/,"").toUpperCase()+" "+encode_binary(rfc822.header)+" ";
 				break;
 			case 'RFC822':
 			case 'BODY[]':
@@ -272,13 +344,28 @@ function send_fetch_response(msgnum, format, uid)
 				// fall-through
 			case 'BODY.PEEK[]':
 				get_rfc822();
-				resp += format[i].replace(/\.PEEK/,"").toUpperCase()+" {"+(rfc822.header.length+rfc822.text.length)+"}\r\n"+rfc822.header+rfc822.text+" ";
+				resp += format[i].replace(/\.PEEK/,"").toUpperCase()+" "+encode_binary(rfc822.header+rfc822.text)+" ";
 				break;
 			case 'BODY[HEADER.FIELDS':
 				set_seen_flag();
 			case 'BODY.PEEK[HEADER.FIELDS':
 				objtype=format[i].replace(/\.PEEK/,"").toUpperCase();
 				break;
+			case 'ENVELOPE':
+				get_envelope();
+				resp += 'ENVELOPE ('+envelope.join(" ")+') ';
+				break;
+			case 'BODYSTRUCTURE':
+				get_rfc822_size();
+				get_rfc822_text();
+				resp += 'BODYSTRUCTURE ("TEXT" "PLAIN" ("CHARSET" "IBM437") NIL NIL "8BIT" '+rfc822.text.length+' '+rfc822.text.split(/\r\n/).length+" NIL NIL NIL) ";
+				break;
+			case 'BODY[1]':
+				set_seen_flag();
+			case 'BODY.PEEK[1]':
+				get_rfc822_text();
+				resp += 'BODY[1] '+encode_binary(rfc822.text)+' ';
+				break;
 		}
 	}
 	if(seen_changed && !sent_flags) {
@@ -287,7 +374,8 @@ function send_fetch_response(msgnum, format, uid)
 	}
 	if(uid && !sent_uid)
 		resp += "UID "+idx.number+" ";
-	resp = resp.substr(0, resp.length-1)+")";
+	resp=resp.replace(/\s*$/,'');
+	resp += ")";
 	untagged(resp);
 }
 
@@ -356,7 +444,7 @@ function parse_seq_set(set, uid) {
 					continue;
 			}
 			else
-				idx=base.get_msg_index(uid?false:true, parseInt(i,10));
+				idx=base.get_msg_index(uid?false:true, parseInt(i,10)-(uid?0:1));
 			if(idx!=null) {
 				response.push(idx.number);
 			}
@@ -838,7 +926,7 @@ function getsub(longname) {
 	return("NONE!!!");
 }
 
-function generate_inbox_map()
+function generate_inbox_map(base)
 {
 	var i;
 	var idx;
@@ -886,7 +974,7 @@ function update_status()
 		return;
 	}
 	if(base.subnum==65535) {
-		inbox_map=generate_inbox_map(true);
+		inbox_map=generate_inbox_map(base);
 		curr_status.exists=inbox_map.uid.length;
 		curr_status.recent=count_recent(base);
 		curr_status.unseen=inbox_map.unseen;
@@ -953,6 +1041,33 @@ function open_sub(sub)
 	return true;
 }
 
+function display_list(cmd, groups)
+{
+	var group;
+	var base;
+
+	for(group in groups) {
+		if(groups[group].substr(-1)==sepchar)
+			untagged(cmd+' (\\Noselect) '+encode_string(sepchar)+' '+encode_string(groups[group].substr(0,groups[group].length-1)));
+		else {
+			if(groups[group] == '') {
+				untagged(cmd+' (\\Noselect) '+encode_string(sepchar)+' '+encode_string(groups[group]));
+			}
+			else {
+				base=new MsgBase(getsub(groups[group]));
+				if(base.cfg != undefined) {
+					if(base.last_msg > msg_area.sub[base.cfg.code].scan_ptr)
+						untagged(cmd+' (\\Noinferiors \\Marked) '+encode_string(sepchar)+' '+encode_string(groups[group]));
+					else
+						untagged(cmd+' (\\Noinferiors \\UnMarked) '+encode_string(sepchar)+' '+encode_string(groups[group]));
+				}
+				else
+					untagged(cmd+' (\\Noinferiors) '+encode_string(sepchar)+' '+encode_string(groups[group]));
+			}
+		}
+	}
+}
+
 authenticated_command_handlers = {
 	SELECT:{
 		arguments:1,
@@ -1048,30 +1163,8 @@ authenticated_command_handlers = {
 			var group=args[1];
 			var sub=args[2];
 			var groups=sublist(group, sub, false);
-			var group;
-			var base;
-			var interesting=false;
-
-			for(group in groups) {
-				if(groups[group].substr(-1)==sepchar)
-					untagged('LIST (\\Noselect) "'+sepchar+'" "'+groups[group].substr(0,groups[group].length-1)+'"');
-				else {
-					if(groups[group] == '') {
-						untagged('LIST (\\Noselect) "'+sepchar+'" "'+groups[group]+'"');
-					}
-					else {
-						base=new MsgBase(getsub(groups[group]));
-						if(base.cfg != undefined) {
-							if(base.last_msg > msg_area.sub[base.cfg.code].scan_ptr)
-								untagged('LIST (\\Noinferiors \\Marked) "'+sepchar+'" "'+groups[group]+'"');
-							else
-								untagged('LIST (\\Noinferiors \\Unmarked) "'+sepchar+'" "'+groups[group]+'"');
-						}
-						else
-							untagged('LIST (\\Noinferiors) "'+sepchar+'" "'+groups[group]+'"');
-					}
-				}
-			}
+
+			display_list("LIST", groups);
 			tagged(tag, "OK", "There you go.");
 		},
 	},
@@ -1084,12 +1177,7 @@ authenticated_command_handlers = {
 			var groups=sublist(group, sub, true);
 			var group;
 
-			for(group in groups) {
-				if(groups[group].substr(-1)==sepchar)
-					untagged('LSUB (\\Noselect) "'+sepchar+'" "'+groups[group].substr(0,groups[group].length-1)+'"');
-				else
-					untagged('LSUB () "'+sepchar+'" "'+groups[group]+'"');
-			}
+			display_list("LSUB", groups);
 			tagged(tag, "OK", "There you go.");
 		},
 	},
@@ -1122,7 +1210,7 @@ authenticated_command_handlers = {
 						response.push("MESSAGES");
 						if(base.subnum==65535) {
 							if(!mademap)
-								inbox_map=generate_inbox_map(false);
+								inbox_map=generate_inbox_map(base);
 							response.push(inbox_map.length);
 						}
 						else
@@ -1144,7 +1232,7 @@ authenticated_command_handlers = {
 						response.push("UNSEEN");
 						if(base.subnum==65535) {
 							if(!mademap)
-								inbox_map=generate_inbox_map();
+								inbox_map=generate_inbox_map(base);
 							response.push(inbox_map.unseen);
 						}
 						else
@@ -1154,7 +1242,7 @@ authenticated_command_handlers = {
 			}
 			base.close();
 			update_status();
-			untagged("STATUS {"+(args[1].length)+"}\r\n"+args[1]+" ("+response.join(" ")+")");
+			untagged("STATUS "+encode_string(args[1])+" ("+response.join(" ")+")");
 			tagged(tag, "OK", "And that's the way it is.");
 		},
 	},