diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigHomeHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigHomeHandler.java
new file mode 100644
index 0000000000000000000000000000000000000000..8ab8c0de4459bb0341be2108528c36809c7d0144
--- /dev/null
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigHomeHandler.java
@@ -0,0 +1,113 @@
+package net.i2p.router.web;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Map;
+
+import net.i2p.data.DataHelper;
+
+/**
+ *  Simple home page configuration.
+ *
+ *  @since 0.9
+ */
+public class ConfigHomeHandler extends FormHandler {
+
+    private Map _settings;
+    
+    @Override
+    protected void processForm() {
+        if (_action == null) return;
+        String group = getJettyString("group");
+        boolean deleting = _action.equals(_("Delete selected"));
+        boolean adding = _action.equals(_("Add item"));
+        boolean restoring = _action.equals(_("Restore defaults"));
+        if (_action.equals(_("Save")) && "0".equals(group)) {
+            boolean old = _context.getBooleanProperty(HomeHelper.PROP_OLDHOME);
+            boolean nnew = getJettyString("oldHome") != null;
+            if (old != nnew) {
+                _context.router().saveConfig(HomeHelper.PROP_OLDHOME, "" + nnew);
+                addFormNotice(_("Home page changed"));
+            }
+        } else if (adding || deleting || restoring) {
+            String prop;
+            String dflt;
+            if ("1".equals(group)) {
+                prop = HomeHelper.PROP_FAVORITES;
+                dflt = HomeHelper.DEFAULT_FAVORITES;
+            } else if ("2".equals(group)) {
+                prop = HomeHelper.PROP_SERVICES;
+                dflt = HomeHelper.DEFAULT_SERVICES;
+            } else if ("3".equals(group)) {
+                prop = SearchHelper.PROP_ENGINES;
+                dflt = SearchHelper.ENGINES_DEFAULT;
+            } else {
+                addFormError("Bad group");
+                return;
+            }
+            if (restoring) {
+                _context.router().saveConfig(prop, dflt);
+                addFormNotice(_("Restored default settings"));
+                return;
+            }
+            String config = _context.getProperty(prop, dflt);
+            Collection<HomeHelper.App> apps;
+            if ("3".equals(group))
+                apps = HomeHelper.buildSearchApps(config);
+            else
+                apps = HomeHelper.buildApps(_context, config);
+            if (adding) {
+                String name = getJettyString("name");
+                if (name == null || name.length() <= 0) {
+                    addFormError(_("No name entered"));
+                    return;
+                }
+                String url = getJettyString("url");
+                if (url == null || url.length() <= 0) {
+                    addFormError(_("No URL entered"));
+                    return;
+                }
+                name = DataHelper.escapeHTML(name).replace(",", "&#44;");   // HomeHelper.S
+                url = DataHelper.escapeHTML(url).replace(",", "&#44;");
+                HomeHelper.App app = new HomeHelper.App(name, "", url, "/themes/console/images/itoopie_sm.png");
+                apps.add(app);
+                addFormNotice(_("Added") + ": " + app.name);
+            } else {
+                // deleting
+                Set<String> toDelete = new HashSet();
+                for (Object o : _settings.keySet()) {
+                     if (!(o instanceof String))
+                         continue;
+                     String k = (String) o;
+                     if (!k.startsWith("delete_"))
+                         continue;
+                     k = k.substring(7);
+                     toDelete.add(k);
+                }
+                for (Iterator<HomeHelper.App> iter = apps.iterator(); iter.hasNext(); ) {
+                    HomeHelper.App app = iter.next();
+                    if (toDelete.contains(app.name)) {
+                        iter.remove();
+                        addFormNotice(_("Removed") + ": " + app.name);
+                    }
+                }
+            }
+            HomeHelper.saveApps(_context, prop, apps, !("3".equals(group)));
+        } else {
+            addFormError(_("Unsupported"));
+        }
+    }
+
+    public void setSettings(Map settings) { _settings = new HashMap(settings); }
+
+    /** curses Jetty for returning arrays */
+    private String getJettyString(String key) {
+        String[] arr = (String[]) _settings.get(key);
+        if (arr == null)
+            return null;
+        return arr[0].trim();
+    }
+}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java
index 5b6fecb8e6e0896312060b69972f64ce6cec6691..eb8d504bb58688242da3dbb0755e122dc1acad12 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigNavHelper.java
@@ -11,12 +11,13 @@ public class ConfigNavHelper extends HelperBase {
 
     /** configX.jsp */
     private static final String pages[] =
-                                          {"", "net", "ui", "service", "update", "tunnels",
+                                          {"", "net", "ui", "home", "service", "update", "tunnels",
                                            "clients", "peer", "keyring", "logging", "stats",
                                            "reseed", "advanced" };
 
     private static final String titles[] =
-                                          {_x("Bandwidth"), _x("Network"), _x("UI"), _x("Service"), _x("Update"), _x("Tunnels"),
+                                          {_x("Bandwidth"), _x("Network"), _x("UI"), _x("Home Page"),
+                                           _x("Service"), _x("Update"), _x("Tunnels"),
                                            _x("Clients"), _x("Peers"), _x("Keyring"), _x("Logging"), _x("Stats"),
                                            _x("Reseeding"), _x("Advanced") };
 
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..d0ab6dc759dcfcf64c55f1b112e05b5e596c7ff3
--- /dev/null
+++ b/apps/routerconsole/java/src/net/i2p/router/web/HomeHelper.java
@@ -0,0 +1,224 @@
+package net.i2p.router.web;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import net.i2p.router.RouterContext;
+import net.i2p.util.PortMapper;
+
+/**
+ *  For /home and /confighome
+ *
+ *  @since 0.9
+ */
+public class HomeHelper extends HelperBase {
+    
+    private static final char S = ',';
+    private static final String I = "/themes/console/images/";
+    static final String PROP_SERVICES = "routerconsole.services";
+    static final String PROP_FAVORITES = "routerconsole.favorites";
+    static final String PROP_OLDHOME = "routerconsole.oldHomePage";
+
+    static final String DEFAULT_SERVICES =
+        _x("Addressbook") + S + _x("Manage your I2P hosts file here (I2P domain name resolution)") + S + "/susidns/index" + S + I + "book_addresses.png" + S +
+        _x("Configure Bandwidth") + S + _x("I2P Bandwidth Configuration") + S + "/config" + S + I + "wrench_orange.png" + S +
+        _x("Customize Home Page") + S + _x("I2P Home Page Configuration") + S + "/confighome" + S + I + "wrench_orange.png" + S +
+        _x("Email") + S + _x("Anonymous webmail client") + S + "/susimail/susimail" + S + I + "email.png" + S +
+        _x("Help") + S + _x("I2P Router Help") + S + "/help" + S + I + "help.png" + S +
+        _x("Router Console") + S + _x("I2P Router Console") + S + "/console" + S + I + "wrench_orange.png" + S +
+        _x("Torrents") + S + _x("Built-in anonymous BitTorrent Client") + S + "/i2psnark/" + S + I + "film.png" + S +
+        _x("Website") + S + _x("Local web server") + S + "http://127.0.0.1:7658/" + S + I + "server.png" + S +
+        "";
+
+    static final String DEFAULT_FAVORITES =
+        _x("Bug Reports") + S + _x("Bug tracker") + S + "http://trac.i2p2.i2p/report/1" + S + I + "bug.png" + S +
+        _x("Dev Forum") + S + _x("Development forum") + S + "http://zzz.i2p/" + S + I + "itoopie_sm.png" + S +
+        _x("diftracker") + S + _x("Bittorrent tracker") + S + "http://diftracker.i2p/" + S + I + "itoopie_sm.png" + S +
+        "echelon.i2p" + S + _x("I2P Applications") + S + "http://echelon.i2p/" + S + I + "itoopie_sm.png" + S +
+        _x("FAQ") + S + _x("Frequently Asked Questions") + S + "http://www.i2p2.i2p/faq" + S + I + "help.png" + S +
+        _x("Forum") + S + _x("Community forum") + S + "http://forum.i2p/" + S + I + "itoopie_sm.png" + S +
+        "i2plugins.i2p" + S + _x("I2P Plugins") + S + "http://i2plugins.i2p/" + S + I + "itoopie_sm.png" + S +
+        "ident.i2p" + S + _x("Short message service") + S + "http://ident.i2p/" + S + I + "itoopie_sm.png" + S +
+        _x("Javadocs") + S + _x("Technical documentation") + S + "http://docs.i2p-projekt.i2p/javadoc/" + S + I + "book.png" + S +
+        _x("Pastebin") + S + _x("I2P Pastebin") + S + "http://pastethis.i2p/" + S + I + "itoopie_sm.png" + S +
+        "Planet I2P" + S + _x("I2P News") + S + "http://planet.i2p/" + S + I + "itoopie_sm.png" + S +
+        _x("Postman's Tracker") + S + _x("Bittorrent tracker") + S + "http://tracker2.postman.i2p/" + S + I + "itoopie_sm.png" + S +
+        _x("Project Website") + S + _x("I2P home page") + S + "http://www.i2p2.i2p/" + S + I + "help.png" + S +
+        "stats.i2p" + S + _x("I2P Netowrk Statistics") + S + "http://stats.i2p/cgi-bin/dashboard.cgi" + S + I + "itoopie_sm.png" + S +
+        _x("Technical Docs") + S + _x("Technical documentation") + S + "http://www.i2p2.i2p/how" + S + I + "book.png" + S +
+        "";
+
+
+    public String getServices() {
+        List<App> plugins = NavHelper.getClientApps(_context);
+        return homeTable(PROP_SERVICES, DEFAULT_SERVICES, plugins);
+    }
+
+    public String getFavorites() {
+        return homeTable(PROP_FAVORITES, DEFAULT_FAVORITES, null);
+    }
+
+    public String getConfigServices() {
+        return configTable(PROP_SERVICES, DEFAULT_SERVICES);
+    }
+
+    public String getConfigFavorites() {
+        return configTable(PROP_FAVORITES, DEFAULT_FAVORITES);
+    }
+
+    public String getConfigSearch() {
+        return configTable(SearchHelper.PROP_ENGINES, SearchHelper.ENGINES_DEFAULT);
+    }
+
+    public String getConfigHome() {
+        boolean oldHome = _context.getBooleanProperty(PROP_OLDHOME);
+        return oldHome ? "checked=\"true\"" : "";
+    }
+
+    public String getProxyStatus() {
+        int port = _context.portMapper().getPort(PortMapper.SVC_HTTP_PROXY);
+        if (port <= 0)
+            return _("The HTTP proxy is not up");
+        return "<img src=\"http://console.i2p/onepixel.png?" + _context.random().nextInt() + "\"" +
+               " alt=\"" + _("Your browser is not properly configured to use the HTTP proxy at {0}",
+                             _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST) + ':' + port) +
+               "\">";
+    }
+
+    private String homeTable(String prop, String dflt, Collection<App> toAdd) {
+        String config = _context.getProperty(prop, dflt);
+        Collection<App> apps = buildApps(_context, config);
+        if (toAdd != null)
+            apps.addAll(toAdd);
+        return renderApps(apps);
+    }
+
+    private String configTable(String prop, String dflt) {
+        String config = _context.getProperty(prop, dflt);
+        Collection<App> apps;
+        if (prop.equals(SearchHelper.PROP_ENGINES))
+            apps = buildSearchApps(config);
+        else
+            apps = buildApps(_context, config);
+        return renderConfig(apps);
+    }
+
+    static Collection<App> buildApps(RouterContext ctx, String config) {
+        String[] args = config.split("" + S);
+        Set<App> apps = new TreeSet(new AppComparator());
+        for (int i = 0; i < args.length - 3; i += 4) {
+            String name = Messages.getString(args[i], ctx);
+            String desc = Messages.getString(args[i+1], ctx);
+            String url = args[i+2];
+            String icon = args[i+3];
+            apps.add(new App(name, desc, url, icon));
+        }
+        return apps;
+    }
+
+    static Collection<App> buildSearchApps(String config) {
+        String[] args = config.split("" + S);
+        Set<App> apps = new TreeSet(new AppComparator());
+        for (int i = 0; i < args.length - 1; i += 2) {
+            String name = args[i];
+            String url = args[i+1];
+            apps.add(new App(name, null, url, null));
+        }
+        return apps;
+    }
+
+    static void saveApps(RouterContext ctx, String prop, Collection<App> apps, boolean full) {
+        StringBuilder buf = new StringBuilder(1024);
+        for (App app : apps) {
+            buf.append(app.name).append(S);
+            if (full)
+                buf.append(app.desc).append(S);
+            buf.append(app.url).append(S);
+            if (full)
+                buf.append(app.icon).append(S);
+        }
+        ctx.router().saveConfig(prop, buf.toString());
+    }
+
+    private static String renderApps(Collection<App> apps) {
+        StringBuilder buf = new StringBuilder(1024);
+        buf.append("<div class=\"appgroup\">");
+        for (App app : apps) {
+            buf.append("<div class=\"app\">" +
+                       "<a href=\"").append(app.url).append("\">" +
+                       "<img class=\"");
+            // toopie is 54x68, not 16x16, needs special alignment and sizing
+            if (app.icon.endsWith("/itoopie_sm.png"))
+                buf.append("app2p");
+            else
+                buf.append("app");
+            buf.append("\" alt=\"\" title=\"").append(app.desc).append("\" src=\"").append(app.icon).append("\"></a><br>\n" +
+                       "<table class=\"app\"><tr class=\"app\"><td class=\"app\">" +
+                       "<div class=\"applabel\">" +
+                       "<a href=\"").append(app.url).append("\" title=\"").append(app.desc).append("\">").append(app.name).append("</a>" +
+                       "</div>" +
+                       "</td></tr></table>" +
+                       "</div>\n");
+        }
+        buf.append("</div>\n");
+        return buf.toString();
+    }
+
+    private String renderConfig(Collection<App> apps) {
+        StringBuilder buf = new StringBuilder(1024);
+        buf.append("<table><tr><th>")
+           .append(_("Remove"))
+           .append("</th><th colspan=\"2\">")
+           .append(_("Name"))
+           .append("</th><th>")
+           .append(_("URL"))
+           .append("</th></tr>\n");
+        for (App app : apps) {
+            buf.append("<tr><td align=\"center\"><input type=\"checkbox\" class=\"optbox\" name=\"delete_")
+               .append(app.name)
+               .append("\"></td><td align=\"center\">");
+            if (app.icon != null) {
+                buf.append("<img height=\"16\" src=\"").append(app.icon).append("\">");
+            }
+            buf.append("</td><td align=\"left\">")
+               .append(app.name)
+               .append("</td><td align=\"left\"><a href=\"")
+               .append(app.url)
+               .append("\">")
+               .append(app.url)
+               .append("</a></td></tr>\n");
+        }
+        buf.append("<tr><td colspan=\"2\" align=\"center\"><b>")
+           .append(_("Add")).append(":</b>" +
+                   "</td><td align=\"left\"><input type=\"text\" name=\"name\"></td>" +
+                   "<td align=\"left\"><input type=\"text\" size=\"40\" name=\"url\"></td></tr>");
+        buf.append("</table>\n");
+        return buf.toString();
+    }
+
+    static class App {
+        public final String name;
+        public final String desc;
+        public final String url;
+        public final String icon;
+
+        public App(String name, String desc, String url, String icon) {
+            this.name = name;
+            this.desc = desc;
+            this.url = url;
+            this.icon = icon;
+        }
+    }
+
+    /** ignore case, current locale */
+    private static class AppComparator implements Comparator<App> {
+        public int compare(App l, App r) {
+            return l.name.toLowerCase().compareTo(r.name.toLowerCase());
+        }
+    }
+}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java
index f34b1614d86c3051635d7ce8c4eee2a8a34a6337..989d5013035dd5a1b9d02e0b176d8f54dbecbd03 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/NavHelper.java
@@ -36,6 +36,7 @@ public class NavHelper {
     
     /**
      *  Translated string is loaded by PluginStarter
+     *  @param ctx unused
      */
     public static String getClientAppLinks(I2PAppContext ctx) {
         if (_apps.isEmpty())
@@ -55,4 +56,34 @@ public class NavHelper {
         }
         return buf.toString();
     }
+    
+    /**
+     *  For HomeHelper
+     *  @param ctx unused
+     *  @return non-null, possibly empty
+     *  @since 0.9
+     */
+    static List<HomeHelper.App> getClientApps(I2PAppContext ctx) {
+        if (_apps.isEmpty())
+            return Collections.EMPTY_LIST;
+        List<HomeHelper.App> rv = new ArrayList(_apps.size());
+        for (Map.Entry<String, String> e : _apps.entrySet()) {
+            String name = e.getKey();
+            String path = e.getValue();
+            if (path == null)
+                continue;
+            String tip = _tooltips.get(name);
+            if (tip == null)
+                tip = "";
+            // hardcoded hack
+            String icon;
+            if (path.equals("/i2pbote/index.jsp"))
+                icon = "/themes/console/images/email.png";
+            else
+                icon = "/themes/console/images/plugin.png";
+            HomeHelper.App app = new HomeHelper.App(name, tip, path, icon);
+            rv.add(app);
+        }
+        return rv;
+    }
 }
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java
new file mode 100644
index 0000000000000000000000000000000000000000..ff07680162b5b43147a4d7a7a14abec9ac3949b1
--- /dev/null
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SearchHelper.java
@@ -0,0 +1,101 @@
+package net.i2p.router.web;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import net.i2p.data.DataHelper;
+import net.i2p.util.PortMapper;
+
+/**
+ *  Helper for searches.
+ *
+ *  @since 0.9
+ */
+public class SearchHelper extends HelperBase {
+
+    private String _engine;
+    private String _query;
+    private Map<String, String> _engines = new TreeMap();
+    
+    private static final char S = ',';
+    static final String PROP_ENGINES = "routerconsole.searchEngines";
+    private static final String PROP_DEFAULT = "routerconsole.searchEngine";
+
+    static final String ENGINES_DEFAULT =
+        "eepsites.i2p" + S + "http://eepsites.i2p/Content/Search/SearchResults.aspx?inpQuery=%s" + S +
+        "epsilon.i2p" + S + "http://epsilon.i2p/search.jsp?q=%s" + S +
+        "sprongle.i2p" + S + "http://sprongle.i2p/sprongle.php?q=%s" + S +
+        "";
+
+    public void setEngine(String s) {
+        _engine = s;
+        if (s != null) {
+            String dflt = _context.getProperty(PROP_DEFAULT);
+            if (!s.equals(dflt))
+                _context.router().saveConfig(PROP_DEFAULT, s);
+        }
+    }
+
+    public void setQuery(String s) {
+        _query = s;
+    }
+
+    private void buildEngineMap() {
+        String config = _context.getProperty(PROP_ENGINES, ENGINES_DEFAULT);
+        String[] args = config.split("" + S);
+        for (int i = 0; i < args.length - 1; i += 2) {
+            String name = args[i];
+            String url = args[i+1];
+            _engines.put(name, url);
+        }
+    }
+
+    public String getSelector() {
+        buildEngineMap();
+        if (_engines.isEmpty())
+            return "<b>No search engines specified</b>";
+        String dflt = _context.getProperty(PROP_DEFAULT);
+        if (dflt == null || !_engines.containsKey(dflt)) {
+            // pick a randome one as default and save it
+            int idx = _context.random().nextInt(_engines.size());
+            int i = 0;
+            for (String name : _engines.keySet()) {
+                dflt = name;
+                if (i++ >= idx) {
+                    _context.router().saveConfig(PROP_DEFAULT, dflt);
+                    break;
+                }
+            }
+        }
+        StringBuilder buf = new StringBuilder(1024);
+        buf.append("<select name=\"engine\">");
+        for (String name : _engines.keySet()) {
+            buf.append("<option value=\"").append(name).append('\"');
+            if (name.equals(dflt))
+                buf.append(" selected=\"true\"");
+            buf.append('>').append(name).append("</option>\n");
+        }
+        buf.append("</select>\n");
+        return buf.toString();
+    }
+
+    /**
+     *  @return null on error
+     */
+    public String getURL() {
+        if (_engine == null || _query == null)
+            return null;
+        _query = DataHelper.escapeHTML(_query).trim();
+        if (_query.length() <= 0)
+            return null;
+        buildEngineMap();
+        String url = _engines.get(_engine);
+        if (url == null)
+            return null;
+        if (url.contains("%s"))
+            url = url.replace("%s", _query);
+        else
+            url += _query;
+        return url;
+    }
+}
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java
index 0c1fb11743ae764608a037354f0580b4d2b357e0..5e22c1edcdd5d0327ce69bdd91687066b4f58192 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryBarRenderer.java
@@ -266,47 +266,7 @@ public class SummaryBarRenderer {
         out.write(buf.toString());
         buf.setLength(0);
 
-
-        boolean anotherLine = false;
-        if (_helper.showFirewallWarning()) {
-            buf.append("<h4><a href=\"/confignet\" target=\"_top\" title=\"")
-               .append(_("Help with firewall configuration"))
-               .append("\">")
-               .append(_("Check network connection and NAT/firewall"))
-               .append("</a></h4>");
-            anotherLine = true;
-        }
-
-        boolean reseedInProgress = Boolean.valueOf(System.getProperty("net.i2p.router.web.ReseedHandler.reseedInProgress")).booleanValue();
-        // If showing the reseed link is allowed
-        if (_helper.allowReseed()) {
-            if (reseedInProgress) {
-                // While reseed occurring, show status message instead
-                buf.append("<i>").append(System.getProperty("net.i2p.router.web.ReseedHandler.statusMessage","")).append("</i><br>");
-            } else {
-                // While no reseed occurring, show reseed link
-                long nonce = _context.random().nextLong();
-                String prev = System.getProperty("net.i2p.router.web.ReseedHandler.nonce");
-                if (prev != null) System.setProperty("net.i2p.router.web.ReseedHandler.noncePrev", prev);
-                System.setProperty("net.i2p.router.web.ReseedHandler.nonce", nonce+"");
-                String uri = _helper.getRequestURI();
-                buf.append("<p><form action=\"").append(uri).append("\" method=\"POST\">\n");
-                buf.append("<input type=\"hidden\" name=\"reseedNonce\" value=\"").append(nonce).append("\" >\n");
-                buf.append("<button type=\"submit\" class=\"reload\" value=\"Reseed\" >").append(_("Reseed")).append("</button></form></p>\n");
-            }
-            anotherLine = true;
-        }
-        // If a new reseed ain't running, and the last reseed had errors, show error message
-        if (!reseedInProgress) {
-            String reseedErrorMessage = System.getProperty("net.i2p.router.web.ReseedHandler.errorMessage","");
-            if (reseedErrorMessage.length() > 0) {
-                buf.append("<i>").append(reseedErrorMessage).append("</i><br>");
-                anotherLine = true;
-            }
-        }
-        if (anotherLine)
-            buf.append("<hr>");
-
+        buf.append(_helper.getFirewallAndReseedStatus());
 
         buf.append("<h3><a href=\"/config\" title=\"")
            .append(_("Configure router bandwidth allocation"))
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
index f28282feaec122f0817ff2c526ab5a340cb3f3c7..cfafb6c7e6610264683ab500776ffc8bfe8bc2f2 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
@@ -662,6 +662,51 @@ public class SummaryHelper extends HelperBase {
         return ConfigRestartBean.renderStatus(getRequestURI(), getAction(), getConsoleNonce());
     }
 
+    /**
+     *  The firewall status and reseed status/buttons
+     *  @since 0.9 moved from SummaryBarRenderer
+     */
+    public String getFirewallAndReseedStatus() {
+        StringBuilder buf = new StringBuilder(256);
+        if (showFirewallWarning()) {
+            buf.append("<h4><a href=\"/confignet\" target=\"_top\" title=\"")
+               .append(_("Help with firewall configuration"))
+               .append("\">")
+               .append(_("Check network connection and NAT/firewall"))
+               .append("</a></h4>");
+        }
+
+        boolean reseedInProgress = Boolean.valueOf(System.getProperty("net.i2p.router.web.ReseedHandler.reseedInProgress")).booleanValue();
+        // If showing the reseed link is allowed
+        if (allowReseed()) {
+            if (reseedInProgress) {
+                // While reseed occurring, show status message instead
+                buf.append("<i>").append(System.getProperty("net.i2p.router.web.ReseedHandler.statusMessage","")).append("</i><br>");
+            } else {
+                // While no reseed occurring, show reseed link
+                long nonce = _context.random().nextLong();
+                String prev = System.getProperty("net.i2p.router.web.ReseedHandler.nonce");
+                if (prev != null) System.setProperty("net.i2p.router.web.ReseedHandler.noncePrev", prev);
+                System.setProperty("net.i2p.router.web.ReseedHandler.nonce", nonce+"");
+                String uri = getRequestURI();
+                buf.append("<p><form action=\"").append(uri).append("\" method=\"POST\">\n");
+                buf.append("<input type=\"hidden\" name=\"reseedNonce\" value=\"").append(nonce).append("\" >\n");
+                buf.append("<button type=\"submit\" class=\"reload\" value=\"Reseed\" >").append(_("Reseed")).append("</button></form></p>\n");
+            }
+        }
+        // If a new reseed ain't running, and the last reseed had errors, show error message
+        if (!reseedInProgress) {
+            String reseedErrorMessage = System.getProperty("net.i2p.router.web.ReseedHandler.errorMessage","");
+            if (reseedErrorMessage.length() > 0) {
+                buf.append("<i>").append(reseedErrorMessage).append("</i><br>");
+            }
+        }
+        if (buf.length() <= 0)
+            return "";
+        buf.append("<hr>");
+        return buf.toString();
+    }
+
     /** output the summary bar to _out */
     public void renderSummaryBar() throws IOException {
         SummaryBarRenderer renderer = new SummaryBarRenderer(_context, this);
diff --git a/apps/routerconsole/jsp/confighome.jsp b/apps/routerconsole/jsp/confighome.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..728527b8546f8c42636c405c8a930fdbf7e1dc9d
--- /dev/null
+++ b/apps/routerconsole/jsp/confighome.jsp
@@ -0,0 +1,84 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html><head>
+<%@include file="css.jsi" %>
+<%=intl.title("config home")%>
+<style type='text/css'>
+input.default {
+    width: 1px;
+    height: 1px;
+    visibility: hidden;
+}
+</style>
+</head><body>
+
+<%@include file="summary.jsi" %>
+<h1><%=intl._("I2P Home Page Configuration")%></h1>
+<div class="main" id="main">
+<%@include file="confignav.jsi" %>
+
+<jsp:useBean class="net.i2p.router.web.ConfigHomeHandler" id="formhandler" scope="request" />
+<% formhandler.storeMethod(request.getMethod()); %>
+<jsp:setProperty name="formhandler" property="*" />
+<jsp:setProperty name="formhandler" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
+<jsp:setProperty name="formhandler" property="settings" value="<%=request.getParameterMap()%>" />
+<jsp:getProperty name="formhandler" property="allMessages" />
+<%
+    String pageNonce = formhandler.getNewNonce();
+%>
+<jsp:useBean class="net.i2p.router.web.HomeHelper" id="homehelper" scope="request" />
+<jsp:setProperty name="homehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
+
+<h3><%=intl._("Default Home Page")%></h3>
+<form action="" method="POST">
+ <input type="hidden" name="nonce" value="<%=pageNonce%>" >
+ <input type="hidden" name="group" value="0">
+ <input type="checkbox" name="oldHome" <jsp:getProperty name="homehelper" property="configHome" /> >
+ <%=intl._("Use old home page")%>
+ <input type="submit" name="action" class="accept" value="<%=intl._("Save")%>" >
+</form>
+
+<h3><%=intl._("Search Engines")%></h3>
+<form action="" method="POST">
+ <input type="hidden" name="nonce" value="<%=pageNonce%>" >
+ <input type="hidden" name="group" value="3">
+ <jsp:getProperty name="homehelper" property="configSearch" />
+ <div class="formaction">
+  <input type="submit" name="action" class="default" value="<%=intl._("Add item")%>" >
+  <input type="submit" name="action" class="delete" value="<%=intl._("Delete selected")%>" >
+  <input type="reset" class="cancel" value="<%=intl._("Cancel")%>" >
+  <input type="submit" name="action" class="reload" value="<%=intl._("Restore defaults")%>" >
+  <input type="submit" name="action" class="add" value="<%=intl._("Add item")%>" >
+ </div>
+</form>
+
+<h3><%=intl._("Recommended Eepsites")%></h3>
+<form action="" method="POST">
+ <input type="hidden" name="nonce" value="<%=pageNonce%>" >
+ <input type="hidden" name="group" value="1">
+ <jsp:getProperty name="homehelper" property="configFavorites" />
+ <div class="formaction">
+  <input type="submit" name="action" class="default" value="<%=intl._("Add item")%>" >
+  <input type="submit" name="action" class="delete" value="<%=intl._("Delete selected")%>" >
+  <input type="reset" class="cancel" value="<%=intl._("Cancel")%>" >
+  <input type="submit" name="action" class="reload" value="<%=intl._("Restore defaults")%>" >
+  <input type="submit" name="action" class="add" value="<%=intl._("Add item")%>" >
+ </div>
+</form>
+
+<h3><%=intl._("Local Services")%></h3>
+<form action="" method="POST">
+ <input type="hidden" name="nonce" value="<%=pageNonce%>" >
+ <input type="hidden" name="group" value="2">
+ <jsp:getProperty name="homehelper" property="configServices" />
+ <div class="formaction">
+  <input type="submit" name="action" class="default" value="<%=intl._("Add item")%>" >
+  <input type="submit" name="action" class="delete" value="<%=intl._("Delete selected")%>" >
+  <input type="reset" class="cancel" value="<%=intl._("Cancel")%>" >
+  <input type="submit" name="action" class="reload" value="<%=intl._("Restore defaults")%>" >
+  <input type="submit" name="action" class="add" value="<%=intl._("Add item")%>" >
+ </div>
+</form>
+</div></div></body></html>
diff --git a/apps/routerconsole/jsp/console.jsp b/apps/routerconsole/jsp/console.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..238e454e7581d9d08d0ee4648f5e634d8762eb1c
--- /dev/null
+++ b/apps/routerconsole/jsp/console.jsp
@@ -0,0 +1,66 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html><head>
+<%@include file="css.jsi" %>
+<%=intl.title("home")%>
+</head><body>
+<%
+    String consoleNonce = System.getProperty("router.consoleNonce");
+    if (consoleNonce == null) {
+        consoleNonce = Long.toString(new java.util.Random().nextLong());
+        System.setProperty("router.consoleNonce", consoleNonce);
+    }
+%>
+
+<%@include file="summary.jsi" %><h1><%=intl._("I2P Router Console")%></h1>
+<div class="news" id="news">
+ <jsp:useBean class="net.i2p.router.web.NewsHelper" id="newshelper" scope="request" />
+ <jsp:setProperty name="newshelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
+<%
+   if (newshelper.shouldShowNews()) {
+       java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getRouterDir(), "docs/news.xml");
+%>
+ <jsp:setProperty name="newshelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
+ <jsp:setProperty name="newshelper" property="maxLines" value="300" />
+ <jsp:getProperty name="newshelper" property="content" />
+ <hr>
+<%
+   }  // shouldShowNews()
+%>
+ <jsp:useBean class="net.i2p.router.web.ConfigUpdateHelper" id="updatehelper" scope="request" />
+ <jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
+ <jsp:getProperty name="updatehelper" property="newsStatus" /><br>
+</div><div class="main" id="main">
+ <jsp:useBean class="net.i2p.router.web.ContentHelper" id="contenthelper" scope="request" />
+ <div class="welcome">
+  <div class="langbox">
+    <a href="/?lang=en&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=us" title="English" alt="English"></a> 
+    <a href="/?lang=ar&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=lang_ar" title="عربية" alt="عربية"></a>
+    <a href="/?lang=zh&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=cn" title="中文" alt="中文"></a> 
+    <a href="/?lang=cs&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=cs" title="Czech" alt="Czech"></a> 
+    <a href="/?lang=da&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=dk" title="Danish" alt="Danish"></a> 
+    <a href="/?lang=de&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
+    <a href="/?lang=ee&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ee" title="Eesti" alt="Eesti"></a> 
+    <a href="/?lang=es&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=es" title="Español" alt="Español"></a> 
+    <a href="/?lang=fi&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=fi" title="Suomi" alt="Suomi"></a> 
+    <a href="/?lang=fr&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=fr" title="Français" alt="Français"></a><br>
+    <a href="/?lang=it&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=it" title="Italiano" alt="Italiano"></a> 
+    <a href="/?lang=nl&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
+    <a href="/?lang=pl&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=pl" title="Polski" alt="Polski"></a> 
+    <a href="/?lang=pt&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
+    <a href="/?lang=ru&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
+    <a href="/?lang=sv&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a>
+    <a href="/?lang=uk&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ua" title="Ukrainian" alt="Ukrainian"></a>
+    <a href="/?lang=vi&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=vn" title="Tiếng Việt" alt="Tiếng Việt"></a>
+  </div>
+  <a name="top"></a>
+  <h2><%=intl._("Welcome to I2P")%></h2>
+ </div>
+ <% java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/readme.html"); %>
+ <jsp:setProperty name="contenthelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
+ <jsp:setProperty name="contenthelper" property="maxLines" value="300" />
+ <jsp:setProperty name="contenthelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
+ <jsp:getProperty name="contenthelper" property="content" />
+</div></body></html>
diff --git a/apps/routerconsole/jsp/home.jsp b/apps/routerconsole/jsp/home.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..382a73aeed1e9177bb31c80898f8556e1fa195f8
--- /dev/null
+++ b/apps/routerconsole/jsp/home.jsp
@@ -0,0 +1,149 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html><head>
+<%@include file="css.jsi" %>
+<%=intl.title("home")%>
+
+<script type="text/javascript">
+var page = "home";
+function ajax(url,target) {
+  // native XMLHttpRequest object
+  if (window.XMLHttpRequest) {
+    req = new XMLHttpRequest();
+    req.onreadystatechange = function() {ajaxDone(target);};
+    req.open("GET", url, true);
+    req.send(null);
+    // IE/Windows ActiveX version
+  } else if (window.ActiveXObject) {
+    req = new ActiveXObject("Microsoft.XMLDOM");
+    if (req) {
+      req.onreadystatechange = function() {ajaxDone(target);};
+      req.open("GET", url, true);
+      req.send(null);
+    }
+  }
+  //setTimeout("ajax(page,'scriptoutput')", 5000);
+}
+
+function ajaxDone(target) {
+  // only if req is "loaded"
+  if (req.readyState == 4) {
+    // only if "OK"
+    if (req.status == 200) {
+      results = req.responseText;
+      document.getElementById(target).innerHTML = results;
+      document.getElementById("langbox").style.display="block";
+      document.getElementById("home").style.display="block";
+    } else {
+      document.getElementById(target).innerHTML="<b><%=intl._("Router is down")%></b>";
+      document.getElementById("home").style.display="none";
+      document.getElementById("langbox").style.display="none";
+    }
+  }
+}
+
+function requestAjax1() { ajax("/xhr1.jsp", "xhr"); }
+function initAjax() { setInterval(requestAjax1, 15000);  }
+
+</script>
+
+
+
+</head><body onload="initAjax()">
+
+
+<%
+    String consoleNonce = System.getProperty("router.consoleNonce");
+    if (consoleNonce == null) {
+        consoleNonce = Long.toString(new java.util.Random().nextLong());
+        System.setProperty("router.consoleNonce", consoleNonce);
+    }
+%>
+
+<div class="routersummaryouter" id="appsummary">
+ <div class="routersummary">
+  <div style="height: 36px;">
+   <!-- fixme theme, translation -->
+   <a href="/console"><img src="/themes/console/light/images/i2plogo.png" alt="I2P Router Console" title="I2P Router Console"></a>
+  </div>
+  <hr>
+  <div id="xhr">
+<!-- for non-script -->
+<%@include file="xhr1.jsi" %>
+  </div>
+ </div>
+</div>
+
+<div class="welcome">
+  <div class="langbox" id="langbox">
+    <a href="/home?lang=en&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=us" title="English" alt="English"></a> 
+    <a href="/home?lang=ar&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=lang_ar" title="عربية" alt="عربية"></a>
+    <a href="/home?lang=zh&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=cn" title="中文" alt="中文"></a> 
+    <a href="/home?lang=da&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=dk" title="Danish" alt="Danish"></a> 
+    <a href="/home?lang=de&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
+    <a href="/home?lang=ee&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ee" title="Eesti" alt="Eesti"></a> 
+    <a href="/home?lang=es&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=es" title="Español" alt="Español"></a> 
+    <a href="/home?lang=fi&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=fi" title="Suomi" alt="Suomi"></a> 
+    <a href="/home?lang=fr&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=fr" title="Français" alt="Français"></a><br>
+    <a href="/home?lang=it&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=it" title="Italiano" alt="Italiano"></a> 
+    <a href="/home?lang=nl&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
+    <a href="/home?lang=pl&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=pl" title="Polski" alt="Polski"></a> 
+    <a href="/home?lang=pt&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
+    <a href="/home?lang=ru&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
+    <a href="/home?lang=sv&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a>
+    <a href="/home?lang=uk&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ua" title="Ukrainian" alt="Ukrainian"></a>
+    <a href="/home?lang=vi&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=vn" title="Tiếng Việt" alt="Tiếng Việt"></a>
+  </div>
+  <h2 class="app"><%=intl._("Welcome to I2P")%></h2>
+</div>
+
+<div class="news" id="news">
+ <jsp:useBean class="net.i2p.router.web.NewsHelper" id="newshelper" scope="request" />
+ <jsp:setProperty name="newshelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
+<%
+   if (newshelper.shouldShowNews()) {
+       java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getRouterDir(), "docs/news.xml");
+%>
+ <h3 class="app"><%=intl._("Latest I2P News")%></h3>
+ <jsp:setProperty name="newshelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
+ <jsp:setProperty name="newshelper" property="maxLines" value="300" />
+ <jsp:getProperty name="newshelper" property="content" />
+ <hr>
+<%
+   }  // shouldShowNews()
+%>
+ <jsp:useBean class="net.i2p.router.web.ConfigUpdateHelper" id="updatehelper" scope="request" />
+ <jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
+ <jsp:getProperty name="updatehelper" property="newsStatus" /><br>
+</div>
+
+<div class="home" id="home">
+  <div class="search">
+    <form action="/search.jsp" method="POST">
+      <table><tr><td align="right">
+        <input size="50" type="text" class="search" name="query" />
+      </td><td align="left">
+        <button type="submit" value="search" class="search"><%=intl._("Search I2P")%></button>
+      </td></tr><tr><td align="right">
+        <b>Using search engine:</b>
+      </td><td align="left">
+        <jsp:useBean class="net.i2p.router.web.SearchHelper" id="searchhelper" scope="request" />
+        <jsp:setProperty name="searchhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
+        <jsp:getProperty name="searchhelper" property="selector" />
+      </td></tr></table>
+    </form>
+  </div>
+  <jsp:useBean class="net.i2p.router.web.HomeHelper" id="homehelper" scope="request" />
+  <jsp:setProperty name="homehelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
+  <div class="ag2">
+    <h4 class="app"><%=intl._("Recommended Eepsites")%></h4>
+    <jsp:getProperty name="homehelper" property="favorites" /><br>
+  </div>
+  <div class="ag2">
+    <h4 class="app"><%=intl._("Local Services")%></h4>
+    <jsp:getProperty name="homehelper" property="services" /><br>
+  </div>
+</div>
+</body></html>
diff --git a/apps/routerconsole/jsp/index.jsp b/apps/routerconsole/jsp/index.jsp
index 238e454e7581d9d08d0ee4648f5e634d8762eb1c..b87cf0a1e15fc3bbd57ee4d9e13c390f1bb61d2e 100644
--- a/apps/routerconsole/jsp/index.jsp
+++ b/apps/routerconsole/jsp/index.jsp
@@ -1,66 +1,18 @@
-<%@page contentType="text/html"%>
+<%@page contentType="text/plain"%>
 <%@page pageEncoding="UTF-8"%>
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
-
-<html><head>
-<%@include file="css.jsi" %>
-<%=intl.title("home")%>
-</head><body>
 <%
-    String consoleNonce = System.getProperty("router.consoleNonce");
-    if (consoleNonce == null) {
-        consoleNonce = Long.toString(new java.util.Random().nextLong());
-        System.setProperty("router.consoleNonce", consoleNonce);
-    }
+    response.setStatus(302, "Moved");
+    String req = request.getRequestURI();
+    if (req.endsWith("index"))
+        req = req.substring(0, req.length() - 5);
+    else if (req.endsWith("index.jsp"))
+        req = req.substring(0, req.length() - 9);
+    if (!req.endsWith("/"))
+        req += '/';
+    boolean oldHome = net.i2p.I2PAppContext.getGlobalContext().getBooleanProperty("routerconsole.oldHomePage");
+    if (oldHome)
+        req += "console";
+    else
+        req += "home";
+    response.setHeader("Location", req);
 %>
-
-<%@include file="summary.jsi" %><h1><%=intl._("I2P Router Console")%></h1>
-<div class="news" id="news">
- <jsp:useBean class="net.i2p.router.web.NewsHelper" id="newshelper" scope="request" />
- <jsp:setProperty name="newshelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
-<%
-   if (newshelper.shouldShowNews()) {
-       java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getRouterDir(), "docs/news.xml");
-%>
- <jsp:setProperty name="newshelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
- <jsp:setProperty name="newshelper" property="maxLines" value="300" />
- <jsp:getProperty name="newshelper" property="content" />
- <hr>
-<%
-   }  // shouldShowNews()
-%>
- <jsp:useBean class="net.i2p.router.web.ConfigUpdateHelper" id="updatehelper" scope="request" />
- <jsp:setProperty name="updatehelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
- <jsp:getProperty name="updatehelper" property="newsStatus" /><br>
-</div><div class="main" id="main">
- <jsp:useBean class="net.i2p.router.web.ContentHelper" id="contenthelper" scope="request" />
- <div class="welcome">
-  <div class="langbox">
-    <a href="/?lang=en&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=us" title="English" alt="English"></a> 
-    <a href="/?lang=ar&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=lang_ar" title="عربية" alt="عربية"></a>
-    <a href="/?lang=zh&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=cn" title="中文" alt="中文"></a> 
-    <a href="/?lang=cs&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=cs" title="Czech" alt="Czech"></a> 
-    <a href="/?lang=da&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=dk" title="Danish" alt="Danish"></a> 
-    <a href="/?lang=de&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
-    <a href="/?lang=ee&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ee" title="Eesti" alt="Eesti"></a> 
-    <a href="/?lang=es&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=es" title="Español" alt="Español"></a> 
-    <a href="/?lang=fi&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=fi" title="Suomi" alt="Suomi"></a> 
-    <a href="/?lang=fr&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=fr" title="Français" alt="Français"></a><br>
-    <a href="/?lang=it&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=it" title="Italiano" alt="Italiano"></a> 
-    <a href="/?lang=nl&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
-    <a href="/?lang=pl&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=pl" title="Polski" alt="Polski"></a> 
-    <a href="/?lang=pt&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
-    <a href="/?lang=ru&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
-    <a href="/?lang=sv&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a>
-    <a href="/?lang=uk&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=ua" title="Ukrainian" alt="Ukrainian"></a>
-    <a href="/?lang=vi&amp;consoleNonce=<%=consoleNonce%>"><img height="11" width="16" style="padding: 0 2px;" src="/flags.jsp?c=vn" title="Tiếng Việt" alt="Tiếng Việt"></a>
-  </div>
-  <a name="top"></a>
-  <h2><%=intl._("Welcome to I2P")%></h2>
- </div>
- <% java.io.File fpath = new java.io.File(net.i2p.I2PAppContext.getGlobalContext().getBaseDir(), "docs/readme.html"); %>
- <jsp:setProperty name="contenthelper" property="page" value="<%=fpath.getAbsolutePath()%>" />
- <jsp:setProperty name="contenthelper" property="maxLines" value="300" />
- <jsp:setProperty name="contenthelper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
- <jsp:getProperty name="contenthelper" property="content" />
-</div></body></html>
diff --git a/apps/routerconsole/jsp/search.jsp b/apps/routerconsole/jsp/search.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..6e8ddf9b4b182e1610490304fa73190a188b2d41
--- /dev/null
+++ b/apps/routerconsole/jsp/search.jsp
@@ -0,0 +1,34 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+<jsp:useBean class="net.i2p.router.web.SearchHelper" id="searchhelper" scope="request" />
+<jsp:setProperty name="searchhelper" property="contextId" value="<%=(String)session.getAttribute(\"i2p.contextId\")%>" />
+<jsp:setProperty name="searchhelper" property="engine" value="<%=request.getParameter("engine")%>" />
+<jsp:setProperty name="searchhelper" property="query" value="<%=request.getParameter("query")%>" />
+<html><head></head><body><b>
+<%
+    String url = searchhelper.getURL();
+    if (url != null) {
+        response.setStatus(303, "Redirecting");
+        response.setHeader("Location", url);
+%>
+Searching...
+<%
+    } else {
+        response.setStatus(403, "Bad");
+        String query = request.getParameter("query");
+        if (query == null || query.trim().length() <= 0) {
+%>
+No search string specified!
+<%
+        } else if (request.getParameter("engine") == null) {
+%>
+No search engine specified!
+<%
+        } else {
+%>
+No search engines found!
+<%
+        }
+    }
+%>
+</b></body></html>
diff --git a/apps/routerconsole/jsp/xhr1.jsi b/apps/routerconsole/jsp/xhr1.jsi
new file mode 100644
index 0000000000000000000000000000000000000000..c9722c69b54ab9f60d09eb6708d62f207a05196c
--- /dev/null
+++ b/apps/routerconsole/jsp/xhr1.jsi
@@ -0,0 +1,24 @@
+<jsp:useBean class="net.i2p.router.web.SummaryHelper" id="helper" scope="request" />
+<jsp:setProperty name="helper" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
+<jsp:setProperty name="helper" property="action" value="<%=request.getParameter("action")%>" />
+<table><tr><td align="left"><b><%=intl._("Version")%>:</b></td><td align="right">
+<jsp:getProperty name="helper" property="version" />
+</td></tr><tr><td align="left"><b><%=intl._("Uptime")%>:</b></td><td align="right">
+<jsp:getProperty name="helper" property="uptime" />
+</td></tr></table><hr>
+<jsp:setProperty name="helper" property="updateNonce" value="<%=request.getParameter("updateNonce")%>" />
+<jsp:setProperty name="helper" property="consoleNonce" value="<%=request.getParameter("consoleNonce")%>" />
+<%
+    String reqURI = request.getRequestURI();
+    if (reqURI != null)
+        reqURI = reqURI.replace("/xhr1.jsp", "/home");
+    helper.setRequestURI(reqURI);
+%>
+<h4><a href="/confignet#help" title="<%=intl._("Help with configuring your firewall and router for optimal I2P performance")%>"><%=intl._("Network")%>:
+<jsp:getProperty name="helper" property="reachability" /></a></h4>
+<hr>
+<jsp:getProperty name="helper" property="updateStatus" />
+<jsp:getProperty name="helper" property="restartStatus" />
+<hr>
+<jsp:getProperty name="helper" property="firewallAndReseedStatus" />
+<jsp:getProperty name="helper" property="destinations" />
diff --git a/apps/routerconsole/jsp/xhr1.jsp b/apps/routerconsole/jsp/xhr1.jsp
new file mode 100644
index 0000000000000000000000000000000000000000..effeccbbea2a810ebbb1ebc684445abe11f3dc03
--- /dev/null
+++ b/apps/routerconsole/jsp/xhr1.jsp
@@ -0,0 +1,14 @@
+<%@page contentType="text/html"%>
+<%@page pageEncoding="UTF-8"%>
+<%
+   // http://www.crazysquirrel.com/computing/general/form-encoding.jspx
+   if (request.getCharacterEncoding() == null)
+       request.setCharacterEncoding("UTF-8");
+
+   if (request.getParameter("i2p.contextId") != null) {
+       session.setAttribute("i2p.contextId", request.getParameter("i2p.contextId"));
+   }
+%>
+<jsp:useBean class="net.i2p.router.web.CSSHelper" id="intl" scope="request" />
+<jsp:setProperty name="intl" property="contextId" value="<%=(String)session.getAttribute("i2p.contextId")%>" />
+<%@include file="xhr1.jsi" %>
diff --git a/installer/resources/themes/console/light/console.css b/installer/resources/themes/console/light/console.css
index 0b795718f5bbdf55f9c3eef792e07edab7faf4e2..6db7c481eaf864b84eea866bf43e3eefc9a134ee 100644
--- a/installer/resources/themes/console/light/console.css
+++ b/installer/resources/themes/console/light/console.css
@@ -635,12 +635,24 @@ div.search {
      width: auto;
 }
 
+div.search table {
+     background: none;
+     margin: 20px;
+     padding: 8px;
+     width: auto;
+}
+
 img.app {
-     height: 48px;
-     width: 48px;
+     height: 40px;
+     width: 40px;
      padding: 8px;
 }
 
+img.app2p {
+     height: 48px;
+     padding: 3px 8px;
+}
+
 table.app {
      background: none;
      border: 0;