diff --git a/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java b/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java
index c9995b93533f1b6eead9189dd7a3039905167282..03c6dc5cd1746915336b1dfd8c3f7d1365482418 100644
--- a/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java
+++ b/apps/syndie/java/src/net/i2p/syndie/sml/ThreadedHTMLRenderer.java
@@ -114,6 +114,28 @@ public class ThreadedHTMLRenderer extends HTMLRenderer {
         return buf.toString();
     }
     
+    public static String getViewPostLink(String uri, BlogURI post, User user, boolean isPermalink, 
+                                         String offset, String tags, String author) {
+        StringBuffer buf = new StringBuffer(64);
+        buf.append(uri);
+        buf.append('?').append(PARAM_VISIBLE).append('=');
+        buf.append(post.getKeyHash().toBase64()).append('/');
+        buf.append(post.getEntryId()).append('&');
+        buf.append(PARAM_VIEW_POST).append('=');
+        buf.append(post.getKeyHash().toBase64()).append('/');
+        buf.append(post.getEntryId()).append('&');
+        
+        if (!isPermalink) {
+            if (!empty(offset))
+                buf.append(PARAM_OFFSET).append('=').append(offset).append('&');
+            if (!empty(tags))
+                buf.append(PARAM_TAGS).append('=').append(tags).append('&');
+            if (!empty(author))
+                buf.append(PARAM_AUTHOR).append('=').append(author).append('&');
+        }
+        
+        return buf.toString();
+    }
     
     private static final boolean empty(String val) { return (val == null) || (val.trim().length() <= 0); }
     
diff --git a/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java b/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java
index 853d0a74254bcc85d71cf8b6075a6f9e28e258a5..90405ffcb17a7b8d03b959f8fda92aced4fdd226 100644
--- a/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java
+++ b/apps/syndie/java/src/net/i2p/syndie/web/BaseServlet.java
@@ -800,6 +800,12 @@ public abstract class BaseServlet extends HttpServlet {
                                                     req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS), 
                                                     req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
     }
+    protected String getViewPostLink(HttpServletRequest req, BlogURI post, User user) {
+        return ThreadedHTMLRenderer.getViewPostLink(req.getRequestURI(), post, user, false, 
+                                                    req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET), 
+                                                    req.getParameter(ThreadedHTMLRenderer.PARAM_TAGS), 
+                                                    req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR));
+    }
     protected String getViewThreadLink(HttpServletRequest req, ThreadNode node, User user) {
         return getViewThreadLink(req.getRequestURI(), node, user,
                                  req.getParameter(ThreadedHTMLRenderer.PARAM_OFFSET),
@@ -926,9 +932,6 @@ public abstract class BaseServlet extends HttpServlet {
 "	text-align: left;\n" +
 "	align: left;\n" +
 "}\n" +
-".threadRight {\n" +
-"	text-align: right;\n" +
-"}\n" +
 ".threadNav {\n" +
 "	background-color: #BBBBBB;\n" +
 "}\n" +
@@ -942,6 +945,16 @@ public abstract class BaseServlet extends HttpServlet {
 "                   margin: 0 5px 0 0;\n" +
 "	display: inline;\n" +
 "}\n" +    
+".threadInfoLeft {\n" +
+"                   float: left;\n" +
+"                   margin: 5px 0px 0 0;\n" +
+"	display: inline;\n" +
+"}\n" +    
+".threadInfoRight {\n" +
+"                   float: right;\n" +
+"                   margin: 0 5px 0 0;\n" +
+"	display: inline;\n" +
+"}\n" +    
 ".postMeta {\n" +
 "	background-color: #BBBBFF;\n" +
 "}\n" +
diff --git a/apps/syndie/java/src/net/i2p/syndie/web/ViewThreadedServlet.java b/apps/syndie/java/src/net/i2p/syndie/web/ViewThreadedServlet.java
index d0dd7666e9cebb654f00cf7f3c95e4ad44c7fb57..a6bd2e85296b9477bb59b147e3ae94fc1617d0cd 100644
--- a/apps/syndie/java/src/net/i2p/syndie/web/ViewThreadedServlet.java
+++ b/apps/syndie/java/src/net/i2p/syndie/web/ViewThreadedServlet.java
@@ -173,9 +173,11 @@ public class ViewThreadedServlet extends BaseServlet {
         else
             out.write("<tr class=\"threadOdd\">\n");
 
-        out.write("<td class=\"threadFlag\">");
+        out.write("<td class=\"thread\" colspan=\"3\">");
+        out.write("<span class=\"threadInfoLeft\">");
+        //out.write("<td class=\"threadFlag\">");
         out.write(getFlagHTML(user, node));
-        out.write("</td>\n<td class=\"threadLeft\">\n");
+        //out.write("</td>\n<td class=\"threadLeft\" colspan=\"2\">\n");
         for (int i = 0; i < depth; i++)
             out.write("<img src=\"images/threadIndent.png\" alt=\"\" border=\"0\" />");
         
@@ -250,7 +252,7 @@ public class ViewThreadedServlet extends BaseServlet {
         out.write(getViewPostLink(req, node, user, false));
         out.write("\" title=\"View post\">");
         long dayBegin = BlogManager.instance().getDayBegin();
-        long postId = node.getMostRecentPostDate();
+        long postId = node.getEntry().getEntryId();
         if (postId >= dayBegin) {
             out.write("<b>today</b>");
         } else if (postId >= dayBegin - 24*60*60*1000) {
@@ -270,16 +272,33 @@ public class ViewThreadedServlet extends BaseServlet {
         if (subject == null)
             subject = "";
         out.write(trim(subject, 40));
-        out.write("</a>\n</td><td class=\"threadRight\">\n");
+        //out.write("</a>\n</td><td class=\"threadRight\">\n");
+        out.write("</a></span><span class=\"threadInfoRight\">");
         if (childCount > 0) {
+            out.write(" <a href=\"");
+            out.write(getViewPostLink(req, new BlogURI(node.getMostRecentPostAuthor(), node.getMostRecentPostDate()), user));
+            out.write("\" title=\"View the most recent post\">latest - ");
+         
+            postId = node.getMostRecentPostDate();
+            if (postId >= dayBegin) {
+                out.write("<b>today</b>");
+            } else if (postId >= dayBegin - 24*60*60*1000) {
+                out.write("<b>yesterday</b>");
+            } else {
+                int daysAgo = (int)((dayBegin - postId + 24*60*60*1000-1)/(24*60*60*1000));
+                out.write(daysAgo + " days ago");
+            }
+            
+            out.write("</a>\n");
             out.write(" <a href=\"");
             out.write(getViewThreadLink(req, node, user));
-            out.write("\" title=\"View all posts in the thread\">view thread</a>\n");
+            out.write("\" title=\"View all posts in the thread\">full thread</a>\n");
         } else {
             out.write("<a href=\"");
             out.write(getViewPostLink(req, node, user, false));
             out.write("\" title=\"View the post\">view post</a>\n");
         }
+        out.write("</span>");
         out.write("</td></tr>\n");
         
         boolean rendered = true;
diff --git a/history.txt b/history.txt
index 6b3a68b25d9bb1913150f520de0b919481bad03e..3777ba7f81dc1b871d73f9c6abe982d528d98c8b 100644
--- a/history.txt
+++ b/history.txt
@@ -1,4 +1,9 @@
-$Id: history.txt,v 1.328 2005/11/24 03:45:57 jrandom Exp $
+$Id: history.txt,v 1.329 2005/11/25 06:06:03 jrandom Exp $
+
+2005-11-25  jrandom
+    * Further Syndie UI cleanups
+    * Logging cleanup
+    * Fixed link to fproxy.tino.i2p (thanks zzz!)
 
 2005-11-25  jrandom
     * Don't publish stats for periods we haven't reached yet (thanks zzz!)
diff --git a/readme.html b/readme.html
index 83f4031ac80a853d61ed1a284245cff6fb5407d3..c7b0e37010bc0b8e0ce500408682440109cde57d 100644
--- a/readme.html
+++ b/readme.html
@@ -17,7 +17,7 @@ you can:</p>
          <li><a href="http://search.i2p/">search.i2p</a>: an anonymously hosted search engine of eepsites</li>
          <li><a href="http://ugha.i2p/">ugha.i2p</a>: ugha's eepsite, a wiki that anyone can edit, and lots of links</li>
          <li><a href="http://dev.i2p/">dev.i2p</a>: a secure and anonymous connection to <a href="http://dev.i2p.net/">dev.i2p.net</a></li>
-         <li>Freenet proxies: <a href="http://fproxy.i2p/">fproxy.i2p</a> and <a href="fproxy.tino.i2p">fproxy.tino.i2p</a></li>
+         <li>Freenet proxies: <a href="http://fproxy.i2p/">fproxy.i2p</a> and <a href="http://fproxy.tino.i2p">fproxy.tino.i2p</a></li>
      </ul>
      There are many more eepsites - just follow the links from the ones you see,
      bookmark your favorites, and visit them often!</li>
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index 21bc31c29e4d6c21f6fd48383a158c5c7bdce86c..475ef4453036490ba44442210dac0ea4f30fdebc 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
  *
  */
 public class RouterVersion {
-    public final static String ID = "$Revision: 1.296 $ $Date: 2005/11/24 03:45:56 $";
+    public final static String ID = "$Revision: 1.297 $ $Date: 2005/11/25 06:06:02 $";
     public final static String VERSION = "0.6.1.5";
-    public final static long BUILD = 7;
+    public final static long BUILD = 8;
     public static void main(String args[]) {
         System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
         System.out.println("Router ID: " + RouterVersion.ID);
diff --git a/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java b/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
index 833c698d180dfa28c029b90e3af19d13de0d9c4d..31f6e94e681ead51e947bcd3d8863a250653ad58 100644
--- a/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
+++ b/router/java/src/net/i2p/router/transport/udp/InboundMessageState.java
@@ -53,11 +53,7 @@ public class InboundMessageState {
     public boolean receiveFragment(UDPPacketReader.DataReader data, int dataFragment) {
         int fragmentNum = data.readMessageFragmentNum(dataFragment);
         if ( (fragmentNum < 0) || (fragmentNum > _fragments.length)) {
-            StringBuffer buf = new StringBuffer(1024);
-            buf.append("Invalid fragment ").append(fragmentNum);
-            buf.append(": ").append(data);
-            //data.toRawString(buf);
-            _log.error(buf.toString());
+            _log.error("Invalid fragment " + fragmentNum + "/" + _fragments.length);
             return false;
         }
         if (_fragments[fragmentNum] == null) {
@@ -77,10 +73,7 @@ public class InboundMessageState {
                                + ", isLast=" + isLast
                                + ", data=" + Base64.encode(message.getData(), 0, size));
             } catch (ArrayIndexOutOfBoundsException aioobe) {
-                StringBuffer buf = new StringBuffer(1024);
-                buf.append("Corrupt SSU fragment ").append(fragmentNum);
-                buf.append(": ").append(data);
-                _log.error(buf.toString(), aioobe);
+                _log.error("Corrupt SSU fragment " + fragmentNum, aioobe);
                 return false;
             }
         } else {