diff --git a/apps/susimail/src/src/i2p/susi/webmail/MailPart.java b/apps/susimail/src/src/i2p/susi/webmail/MailPart.java
index 14d4075acf75a0c1482276b23c7831720b1413f3..22eeae2b4bacd4e9da1efb1e496b7a6cef55f1e7 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/MailPart.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/MailPart.java
@@ -94,17 +94,18 @@ class MailPart {
 
 		for( int i = 0; i < headerLines.length; i++ )
 		{
-			if( headerLines[i].toLowerCase(Locale.US).startsWith( "content-transfer-encoding: " ) ) {
+			String hlc = headerLines[i].toLowerCase(Locale.US);
+			if( hlc.startsWith( "content-transfer-encoding: " ) ) {
 				x_encoding = getFirstAttribute( headerLines[i] ).toLowerCase(Locale.US);
 			}
-			else if( headerLines[i].toLowerCase(Locale.US).startsWith( "content-disposition: " ) ) {
+			else if( hlc.startsWith( "content-disposition: " ) ) {
 				x_disposition = getFirstAttribute( headerLines[i] ).toLowerCase(Locale.US);
 				String str;
 				str = getHeaderLineAttribute( headerLines[i], "filename" );
 				if( str != null )
 					x_name = str;
 			}
-			else if( headerLines[i].toLowerCase(Locale.US).startsWith( "content-type: " ) ) {
+			else if( hlc.startsWith( "content-type: " ) ) {
 				x_type = getFirstAttribute( headerLines[i] ).toLowerCase(Locale.US);
 				/*
 				 * extract boundary, name and charset from content type
@@ -124,10 +125,10 @@ class MailPart {
 				if( str != null )
 					x_charset = str.toUpperCase(Locale.US);
 			}
-			else if( headerLines[i].toLowerCase(Locale.US).startsWith( "content-description: " ) ) {
+			else if( hlc.startsWith( "content-description: " ) ) {
 				x_description = getFirstAttribute( headerLines[i] );
 			}
-			else if( headerLines[i].toLowerCase(Locale.US).startsWith( "mime-version: " ) ) {
+			else if( hlc.startsWith( "mime-version: " ) ) {
 				x_version = getFirstAttribute( headerLines[i] );
 			}
 		}
diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/Base64.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/Base64.java
index 0572ec4bfd96a956b589eab8480ba1823df0aad0..be82a28a14217a9a2544ca9b48c769be5832da99 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/encoding/Base64.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/Base64.java
@@ -31,16 +31,11 @@ import java.io.InputStream;
 import java.io.StringWriter;
 import java.io.Writer;
 
-import net.i2p.data.DataHelper;
-
 /**
  * @author susi
  */
 public class Base64 extends Encoding {
 	
-	/* (non-Javadoc)
-	 * @see i2p.susi23.util.Encoding#getName()
-	 */
 	public String getName() {
 		return "base64";
 	}
@@ -166,9 +161,6 @@ public class Base64 extends Encoding {
 		return b;
 	}
 
-	/**
-	 * @see Base64#decode(String)
-	 */
 	public ReadBuffer decode(byte[] in, int offset, int length) throws DecodingException {
 		byte out[] = new byte[length * 3 / 4 + 1 ];
 		int written = 0;
@@ -197,7 +189,7 @@ public class Base64 extends Encoding {
 				length -= 4;
 			}
 			else {
-				System.err.println( "" );
+				//System.err.println( "" );
 				throw new DecodingException( "Decoding base64 failed (trailing garbage)." );
 			}
 		}
diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/EightBit.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/EightBit.java
index b385aadd8d7bcd2fa16a08c520e60a619c8d9ea8..e19b035b5686bd32d8fae9acc563ba5596665cdc 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/encoding/EightBit.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/EightBit.java
@@ -25,30 +25,32 @@ package i2p.susi.webmail.encoding;
 
 import i2p.susi.util.ReadBuffer;
 
-import net.i2p.data.DataHelper;
-
 /**
+ * Decode only. See encode().
  * @author susi
  */
 public class EightBit extends Encoding {
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#getName()
-	 */
 	public String getName() {
 		return "8bit";
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#encode(byte[])
+	/**
+	 * TODO would be nice to implement this, as it is supported on the project server,
+	 * but content must be CRLF terminated with a max of 998 chars per line.
+	 * And you can't have leading dots either, we'd have to prevent or double-dot it.
+	 * That would be expensive to check, using either a double read or
+	 * pulling it all into memory.
+	 * So it's prohibitive for attachments. We could do it for the message body,
+	 * since it's in memory already, but that's not much of a win.
+	 * ref: https://stackoverflow.com/questions/29510178/how-to-handle-1000-character-lines-in-8bit-mime
+	 *
+	 * @throws EncodingException always
 	 */
 	public String encode(byte[] in) throws EncodingException {
 		throw new EncodingException("unsupported");
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#decode(byte[], int, int)
-	 */
 	public ReadBuffer decode(byte[] in, int offset, int length)
 		throws DecodingException {
 		return new ReadBuffer(in, offset, length);
diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/Encoding.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/Encoding.java
index 77123b062b0443ebe4c7490741c8c87e289c539f..a6a9d74798c79a331f68317124508802d2ba9bf6 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/encoding/Encoding.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/Encoding.java
@@ -42,7 +42,12 @@ public abstract class Encoding {
 	public abstract String getName();
 
 	/**
-	 * Encode a byte array to a ASCII or ISO-8859-1 String
+	 * Encode a byte array to a ASCII or ISO-8859-1 String.
+	 * Output must be SMTP-safe: Line length of 998 or less,
+	 * using SMTP-safe characters,
+	 * followed by \r\n, and must not start with a '.'
+	 * unless escaped by a 2nd dot.
+	 * For some encodings, max line length is 76.
 	 * 
 	 * @param in
 	 * @return Encoded string.
@@ -51,7 +56,12 @@ public abstract class Encoding {
 	public abstract String encode( byte in[] ) throws EncodingException;
 
 	/**
-	 * Encode a (UTF-8) String to a ASCII or ISO-8859-1 String
+	 * Encode a (UTF-8) String to a ASCII or ISO-8859-1 String.
+	 * Output must be SMTP-safe: Line length of 998 or less,
+	 * using SMTP-safe characters,
+	 * followed by \r\n, and must not start with a '.'
+	 * unless escaped by a 2nd dot.
+	 * For some encodings, max line length is 76.
 	 * 
 	 * This implementation just converts the string to a byte array
 	 * and then calls encode(byte[]).
@@ -67,6 +77,13 @@ public abstract class Encoding {
 	}
 
 	/**
+	 * Encode an input stream of bytes to a ASCII or ISO-8859-1 String.
+	 * Output must be SMTP-safe: Line length of 998 or less,
+	 * using SMTP-safe characters,
+	 * followed by \r\n, and must not start with a '.'
+	 * unless escaped by a 2nd dot.
+	 * For some encodings, max line length is 76.
+	 * 
 	 *  This implementation just reads the whole stream into memory
 	 *  and then calls encode(byte[]).
 	 *  Subclasses should implement a more memory-efficient method
diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/HTML.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/HTML.java
index 1be6733ae995a596282aa2984279cf68e8c56652..0bfc3244974c27c2b1a50cc9a14e760407847f51 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/encoding/HTML.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/HTML.java
@@ -30,23 +30,14 @@ import i2p.susi.util.ReadBuffer;
  */
 public class HTML extends Encoding {
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#getName()
-	 */
 	public String getName() {
 		return "HTML";
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#encode(byte[])
-	 */
 	public String encode(byte[] in) throws EncodingException {
 		throw new EncodingException("unsupported");
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#encode(java.lang.String)
-	 */
 	@Override
 	public String encode(String str) throws EncodingException
 	{
@@ -56,9 +47,6 @@ public class HTML extends Encoding {
 			   .replaceAll( "\r{0,1}\n", "<br>\r\n" );
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#decode(byte[], int, int)
-	 */
 	public ReadBuffer decode(byte[] in, int offset, int length)
 		throws DecodingException {
 		throw new DecodingException("unsupported");
diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/HeaderLine.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/HeaderLine.java
index 509d889d3603936574a2616ccfc3b43000e68251..560eaa330ecc0e0f77d900660f8d62ccdeba935b 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/encoding/HeaderLine.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/HeaderLine.java
@@ -44,17 +44,13 @@ import net.i2p.data.DataHelper;
  */
 public class HeaderLine extends Encoding {
 	public static final String NAME = "HEADERLINE";
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#getName()
-	 */
+
 	public String getName() {
 		return NAME;
 	}
 
 	private static final int BUFSIZE = 2;
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#encode(byte[])
-	 */
+
 	public String encode( byte in[] ) throws EncodingException {
 		StringBuilder out = new StringBuilder();
 		int l = 0, buffered = 0, tmp[] = new int[BUFSIZE];
@@ -148,9 +144,6 @@ public class HeaderLine extends Encoding {
 		return out.toString();
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#decode(java.lang.String)
-	 */
 	public ReadBuffer decode( byte in[], int offset, int length ) throws DecodingException {
 		ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
 		int written = 0;
diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/QuotedPrintable.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/QuotedPrintable.java
index e4b769657da32b059b314dd6ba3c0b080bec9a8f..30ec5d81196012ff49f2a12e1ceccf28f7bca431 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/encoding/QuotedPrintable.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/QuotedPrintable.java
@@ -32,26 +32,18 @@ import java.io.InputStream;
 import java.io.StringWriter;
 import java.io.Writer;
 
-import net.i2p.data.DataHelper;
-
 /**
  * ref: https://en.wikipedia.org/wiki/Quoted-printable
  * @author susi
  */
 public class QuotedPrintable extends Encoding {
 	
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#getName()
-	 */
 	public String getName() {
 		return "quoted-printable";
 	}
 
 	private static int BUFSIZE = 2;
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#encode(byte[])
-	 */
 	public String encode( byte in[] ) throws EncodingException {
 		try {
 			StringWriter strBuf = new StringWriter();
@@ -142,9 +134,6 @@ public class QuotedPrintable extends Encoding {
 		}
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi.webmail.encoding.Encoding#decode(byte[], int, int)
-	 */
 	public ReadBuffer decode(byte[] in, int offset, int length) {
 		byte[] out = new byte[length];
 		int written = 0;
diff --git a/apps/susimail/src/src/i2p/susi/webmail/encoding/SevenBit.java b/apps/susimail/src/src/i2p/susi/webmail/encoding/SevenBit.java
index 0cf84d063ffd4ebd69652f6de735aed9914c0f17..7bca4b47db13621dc5d45b731c65fc79e309d781 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/encoding/SevenBit.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/encoding/SevenBit.java
@@ -25,29 +25,25 @@ package i2p.susi.webmail.encoding;
 
 import i2p.susi.util.ReadBuffer;
 
-import net.i2p.data.DataHelper;
-
 /**
+ * Decode only.
  * @author susi
  */
 public class SevenBit extends Encoding {
 
-	/* (non-Javadoc)
-	 * @see i2p.susi23.mail.encoding.Encoding#getName()
-	 */
 	public String getName() {
 		return "7bit";
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi23.mail.encoding.Encoding#encode(byte[])
+        /**
+	 * @throws EncodingException always
 	 */
 	public String encode(byte[] in) throws EncodingException {
 		throw new EncodingException("unsupported");
 	}
 
-	/* (non-Javadoc)
-	 * @see i2p.susi23.mail.encoding.Encoding#decode(byte[], int, int)
+        /**
+	 * @throws DecodingException on illegal characters
 	 */
 	public ReadBuffer decode(byte[] in, int offset, int length)
 			throws DecodingException {
diff --git a/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java b/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java
index 2383625a852486e3c7c4d2cf00ecc9ef113a2275..cf40c05c58726d0fbf22295ad0cdec2358438e66 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/smtp/SMTPClient.java
@@ -64,7 +64,8 @@ public class SMTPClient {
 	private Socket socket;
 	public String error;
 	private String lastResponse;
-	private boolean supportsPipelining;
+	private boolean supportsPipelining, eightBitMime;
+	private long maxSize = DEFAULT_MAX_SIZE;
 	
 	private static final Encoding base64;
 	
@@ -258,12 +259,44 @@ public class SMTPClient {
 				socket.setSoTimeout(60*1000);
 				Result r = getFullResult();
 				if (r.result == 250) {
-					supportsPipelining = r.recv.contains("PIPELINING");
+					String[] caps = DataHelper.split(r.recv, "\r");
+					for (String c : caps) {
+						if (c.equals("PIPELINING")) {
+							supportsPipelining = true;
+							Debug.debug(Debug.DEBUG, "Server supports pipelining");
+						} else if (c.startsWith("SIZE ")) {
+							try {
+								maxSize = Long.parseLong(c.substring(5));
+								Debug.debug(Debug.DEBUG, "Server max size: " + maxSize);
+							} catch (NumberFormatException nfe) {}
+						} else if (c.equals("8BITMIME")) {
+							// unused, see encoding/EightBit.java
+							eightBitMime = true;
+							Debug.debug(Debug.DEBUG, "Server supports 8bitmime");
+						}
+					}
 				} else {
 					error += _t("Server refused connection") + " (" + r +  ")\n";
 					ok = false;
 				}
 			}
+			if (ok && maxSize < DEFAULT_MAX_SIZE) {
+				Debug.debug(Debug.DEBUG, "Rechecking with new max size");
+				// recalculate whether we'll fit
+				// copied from WebMail
+				long total = body.length();
+				if (attachments != null && !attachments.isEmpty()) {
+					for(Attachment a : attachments) {
+						total += a.getSize();
+					}
+				}
+				long binaryMax = (long) ((maxSize * 57.0d / 78) - 32*1024);
+				if (total > binaryMax) {
+					ok = false;
+					error += _t("Email is too large, max is {0}",
+				                    DataHelper.formatSize2(binaryMax, false) + 'B') + '\n';
+				}
+			}
 			if (ok) {
 				// RFC 4954 says AUTH must be the last but let's assume
 				// that includes the user/pass on following lines