diff --git a/apps/susimail/build.xml b/apps/susimail/build.xml
index 4c79fdfd2a9a6e453076f5ef2fa0b5777fedcc78..bb80ea274432e3781541429ab3f12e73ab9568c0 100644
--- a/apps/susimail/build.xml
+++ b/apps/susimail/build.xml
@@ -62,6 +62,10 @@
         <!-- set if unset -->
         <property name="workspace.changes.tr" value="" />
         <copy file="src/susimail.properties" todir="src/WEB-INF/classes" />
+        <mkdir dir="src/WEB-INF/classes/icons" />
+        <copy todir="src/WEB-INF/classes/icons" >
+            <fileset dir="src/icons" />
+        </copy>	
         <war destfile="susimail.war" webxml="src/WEB-INF/web.xml"
              basedir="src/" excludes="WEB-INF/web.xml LICENSE src/**/*">
             <manifest>
diff --git a/apps/susimail/src/icons/attach.png b/apps/susimail/src/icons/attach.png
new file mode 100644
index 0000000000000000000000000000000000000000..ea897cc9f18ca49aa0f30bad4e6b67e4afc7f498
Binary files /dev/null and b/apps/susimail/src/icons/attach.png differ
diff --git a/apps/susimail/src/icons/flag_red.png b/apps/susimail/src/icons/flag_red.png
new file mode 100644
index 0000000000000000000000000000000000000000..e8a602da7b17a323b2c9afe3d8aac62cb717a0b8
Binary files /dev/null and b/apps/susimail/src/icons/flag_red.png differ
diff --git a/apps/susimail/src/src/i2p/susi/webmail/Mail.java b/apps/susimail/src/src/i2p/susi/webmail/Mail.java
index 0d3c231276f24f3ddb73bff9a4e806dc2c603263..ab1acb62113ed60d7888e1c048d22904dc23eaff 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/Mail.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/Mail.java
@@ -70,6 +70,7 @@ class Mail {
 	private MailPart part;
 	String[] to, cc;        // addresses only, enclosed by <>
 	private boolean isNew, isSpam;
+	public String contentType;
 
 	public String error;
 
@@ -154,6 +155,14 @@ class Mail {
 		this.isNew = isNew;
 	}
 
+	public boolean hasAttachment() {
+		// this isn't right but good enough to start
+		// if part != null query parts instead?
+		return contentType != null &&
+			!contentType.contains("text/plain") &&
+			!contentType.contains("multipart/alternative");
+	}
+
 	/**
 	 * 
 	 * @param address E-mail address to be validated
@@ -348,6 +357,11 @@ class Mail {
 						} else if(line.equals( "X-Spam-Flag: YES" )) {
 							// TODO trust.spam.headers config
 							isSpam = true;
+						} else if(line.toLowerCase(Locale.US).startsWith("content-type:" )) {
+							// this is duplicated in MailPart but
+							// we want to know if we have attachments, even if
+							// we haven't fetched the body
+							contentType = line.substring(13).trim();
 						}
 					}
 				}
diff --git a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java
index babeffbcf599ebdaf123cf1228524b036bdded34..af8a06b47ab86bc93d38acf0cee221acc70aca45 100644
--- a/apps/susimail/src/src/i2p/susi/webmail/WebMail.java
+++ b/apps/susimail/src/src/i2p/susi/webmail/WebMail.java
@@ -399,7 +399,7 @@ public class WebMail extends HttpServlet
 			MailCache mc = mailCache;
 			Folder<String> f = folder;
 			if (mc != null && f != null) {
-				if (mc.getMail(true)) {
+				if (MailCache.FETCH_HEADER) {
 					String[] uidls = mc.getUIDLs();
 					f.setElements(uidls);
 				}
@@ -702,7 +702,7 @@ public class WebMail extends HttpServlet
 						if (!offline) {
 							// prime the cache, request all headers at once
 							// otherwise they are pulled one at a time by sortBy() below
-							mc.getMail(true);
+							mc.getMail(MailCache.FETCH_HEADER);
 						}
 						// get through cache so we have the disk-only ones too
 						String[] uidls = mc.getUIDLs();
@@ -767,25 +767,27 @@ public class WebMail extends HttpServlet
 	}
 	/**
 	 * Process all buttons, which possibly change internal state.
+	 * Also processes ?show=x for a GET
 	 * 
 	 * @param sessionObject
 	 * @param request
+	 * @param isPOST disallow button pushes if false
 	 */
-	private static void processStateChangeButtons(SessionObject sessionObject, RequestWrapper request )
+	private static void processStateChangeButtons(SessionObject sessionObject, RequestWrapper request, boolean isPOST )
 	{
 		/*
 		 * LOGIN/LOGOUT
 		 */
-		if( sessionObject.state == STATE_AUTH )
+		if( sessionObject.state == STATE_AUTH && isPOST )
 			processLogin( sessionObject, request );
 
-		if( sessionObject.state != STATE_AUTH )
+		if( sessionObject.state != STATE_AUTH && isPOST )
 			processLogout( sessionObject, request );
 
 		/*
 		 *  compose dialog
 		 */
-		if( sessionObject.state == STATE_NEW ) {
+		if( sessionObject.state == STATE_NEW && isPOST ) {
 			// We have to make sure to get the state right even if
 			// the user hit the back button previously
 			if( buttonPressed( request, SEND ) ) {
@@ -824,7 +826,7 @@ public class WebMail extends HttpServlet
 		/*
 		 * message dialog
 		 */
-		if( sessionObject.state == STATE_SHOW ) {
+		if( sessionObject.state == STATE_SHOW && isPOST ) {
 			if( buttonPressed( request, LIST ) ) { 
 				sessionObject.state = STATE_LIST;
 			} else if (buttonPressed( request, CANCEL ) ||
@@ -849,7 +851,7 @@ public class WebMail extends HttpServlet
 		 * buttons on both folder and message dialog
 		 */
 		if( sessionObject.state == STATE_SHOW || sessionObject.state == STATE_LIST ) {
-			if( buttonPressed( request, NEW ) ) {
+			if( isPOST && buttonPressed( request, NEW ) ) {
 				sessionObject.state = STATE_NEW;
 			}
 			
@@ -979,8 +981,10 @@ public class WebMail extends HttpServlet
 				}
 			}
 		}
+
 		/*
 		 * folder view
+		 * SHOW is the one parameter that's a link, not a button, so we allow it for GET
 		 */
 		if( sessionObject.state == STATE_LIST || sessionObject.state == STATE_SHOW) {
 			/*
@@ -1039,7 +1043,7 @@ public class WebMail extends HttpServlet
 		if( buttonPressed( request, REFRESH ) ) {
 			sessionObject.mailbox.refresh();
 			sessionObject.error += sessionObject.mailbox.lastError();
-			sessionObject.mailCache.getMail(true);
+			sessionObject.mailCache.getMail(MailCache.FETCH_HEADER);
 			// get through cache so we have the disk-only ones too
 			String[] uidls = sessionObject.mailCache.getUIDLs();
 			if (uidls != null)
@@ -1360,13 +1364,15 @@ public class WebMail extends HttpServlet
                                ua.startsWith("Vodafone"));
     }
 	/**
+	 * The entry point for all web page loads
 	 * 
 	 * @param httpRequest
 	 * @param response
+	 * @param isPOST disallow button pushes if false
 	 * @throws IOException
 	 * @throws ServletException
 	 */
-	private void processRequest( HttpServletRequest httpRequest, HttpServletResponse response )
+	private void processRequest( HttpServletRequest httpRequest, HttpServletResponse response, boolean isPOST )
 	throws IOException, ServletException
 	{
 		String theme = Config.getProperty(CONFIG_THEME, DEFAULT_THEME);
@@ -1418,7 +1424,7 @@ public class WebMail extends HttpServlet
 				processComposeButtons( sessionObject, request );
 		
 			int oldState = sessionObject.state;
-			processStateChangeButtons( sessionObject, request );
+			processStateChangeButtons( sessionObject, request, isPOST );
 			int newState = sessionObject.state;
 			if (oldState != newState)
 				Debug.debug(Debug.DEBUG, "STATE CHANGE from " + oldState + " to " + newState);
@@ -1430,11 +1436,14 @@ public class WebMail extends HttpServlet
 			//	Debug.debug(Debug.DEBUG, "Changed idle from " + oldIdle + " to " + newIdle);
 			//}
 			
-			if( sessionObject.state != STATE_AUTH )
-				processGenericButtons( sessionObject, request );
+			if( sessionObject.state != STATE_AUTH ) {
+				if (isPOST)
+				       processGenericButtons( sessionObject, request );
+			}
 			
 			if( sessionObject.state == STATE_LIST ) {
-				processFolderButtons( sessionObject, request );
+				if (isPOST)
+					processFolderButtons( sessionObject, request );
 				for( Iterator<String> it = sessionObject.folder.currentPageIterator(); it != null && it.hasNext(); ) {
 					String uidl = it.next();
 					Mail mail = sessionObject.mailCache.getMail( uidl, MailCache.FETCH_HEADER );
@@ -1446,7 +1455,8 @@ public class WebMail extends HttpServlet
 			}
 			
 			if( sessionObject.state == STATE_SHOW ) {
-				processMessageButtons( sessionObject, request );
+				if (isPOST)
+					processMessageButtons( sessionObject, request );
 				// If the last message has just been deleted then
 				// sessionObject.state = STATE_LIST and
 				// sessionObject.showUIDL = null
@@ -1734,6 +1744,7 @@ public class WebMail extends HttpServlet
 		}
 		return ok;
 	}
+
 	/**
 	 * 
 	 */
@@ -1741,8 +1752,9 @@ public class WebMail extends HttpServlet
 	public void doGet( HttpServletRequest request, HttpServletResponse response )
 	throws IOException, ServletException
 	{
-		processRequest( request, response );		
+		processRequest( request, response, false );		
 	}
+
 	/**
 	 * 
 	 */
@@ -1750,8 +1762,9 @@ public class WebMail extends HttpServlet
 	public void doPost( HttpServletRequest request, HttpServletResponse response )
 	throws IOException, ServletException
 	{
-		processRequest( request, response );
+		processRequest( request, response, true );
 	}
+
 	/**
 	 * 
 	 * @param out
@@ -1948,7 +1961,10 @@ public class WebMail extends HttpServlet
 			//		", clear=" + sessionObject.clear );
 			out.println( "<tr class=\"list" + bg + "\"><td><input type=\"checkbox\" class=\"optbox\" name=\"check" + i + "\" value=\"1\"" + 
 					( idChecked ? "checked" : "" ) + ">" + "</td><td>" +
-					link + mail.shortSender + "</a></td><td>&nbsp;</td><td>" + link + mail.shortSubject + "</a></td><td>&nbsp;</td><td>" +
+					link + mail.shortSender + "</a></td><td>" +
+					(mail.hasAttachment() ? "<img src=\"/susimail/icons/attach.png\" alt=\"\">" : "&nbsp;") + "</td><td>" +
+					link + mail.shortSubject + "</a></td><td>" +
+					(mail.isSpam() ? "<img src=\"/susimail/icons/flag_red.png\" alt=\"\">" : "&nbsp;") + "</td><td>" +
 					// don't let date get split across lines
 					mail.localFormattedDate.replace(" ", "&nbsp;") + "</td><td>&nbsp;</td><td align=\"right\">" +
 					((mail.getSize() > 0) ? (DataHelper.formatSize2(mail.getSize()) + 'B') : "???") + "</td></tr>" );