diff --git a/apps/i2psnark/java/build.xml b/apps/i2psnark/java/build.xml
index 683e812858dd3db83e17149dbd6c786bd14f6a6c..1d20f7b0f154b4856e79ca8f5d6f104ecbeebbd6 100644
--- a/apps/i2psnark/java/build.xml
+++ b/apps/i2psnark/java/build.xml
@@ -50,6 +50,10 @@
                 <pathelement location="../../jetty/jettylib/javax.servlet.jar" />
                 <!-- jsp-api.jar only present for debian builds -->
                 <pathelement location="../../jetty/jettylib/jsp-api.jar" />
+                <!-- jetty-i2p.jar only for RunStandalone -->
+                <pathelement location="../../jetty/jettylib/jetty-i2p.jar" />
+                <!-- systray.jar only for RunStandalone -->
+                <pathelement location="../../systray/java/build/systray.jar" />
             </classpath>
         </javac>
     </target>
@@ -71,7 +75,7 @@
     <target name="jar" depends="builddep, compile, jarUpToDate, listChangedFiles" unless="jar.uptodate" >
         <!-- set if unset -->
         <property name="workspace.changes.tr" value="" />
-        <jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class" excludes="**/web/* **/messages_*.class">
+        <jar destfile="./build/i2psnark.jar" basedir="./build/obj" includes="**/*.class" excludes="**/web/* **/messages_*.class, **/standalone/*">
             <manifest>
                 <attribute name="Main-Class" value="org.klomp.snark.CommandLine" />
                 <attribute name="Class-Path" value="i2p.jar mstreaming.jar streaming.jar" />
@@ -179,29 +183,113 @@
           <zipfileset dir="./dist/" prefix="i2psnark/" />
         </zip>
     </target>
-    <target name="standalone_prep" depends="war">
+
+    <!-- make a fat jar for standalone -->
+    <target name="standalone_jar" depends="war">
+      <jar destfile="build/i2psnark-standalone.jar">
+        <fileset dir="build/obj" includes="**/standalone/*.class" />
+        <zipfileset src="build/i2psnark.jar" />
+        <zipfileset src="../../../core/java/build/i2p.jar" />
+        <zipfileset src="../../jetty/jettylib/commons-logging.jar"  />
+      <!-- without this we get a warning about 'no JSP support' but that's it
+        <zipfileset src="../../jetty/jettylib/jasper-runtime.jar"  />
+       -->
+        <zipfileset src="../../jetty/jettylib/javax.servlet.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-continuation.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-deploy.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-http.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-i2p.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-io.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-security.jar"  />
+        <zipfileset src="../../jetty/jettylib/jetty-servlet.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-util.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-webapp.jar" />
+        <zipfileset src="../../jetty/jettylib/jetty-xml.jar" />
+        <zipfileset src="../../jetty/jettylib/org.mortbay.jetty.jar"  />
+        <zipfileset src="../../ministreaming/java/build/mstreaming.jar" />
+        <zipfileset src="../../streaming/java/build/streaming.jar" />
+        <zipfileset src="../../systray/java/build/systray.jar" />
+        <manifest>
+            <attribute name="Main-Class" value="org.klomp.snark.standalone.RunStandalone"/>
+            <attribute name="Implementation-Version" value="${full.version}" />
+            <attribute name="Built-By" value="${build.built-by}" />
+            <attribute name="Build-Date" value="${build.timestamp}" />
+            <attribute name="Base-Revision" value="${workspace.version}" />
+            <attribute name="Workspace-Changes" value="${workspace.changes.tr}" />
+        </manifest>
+      </jar>
+    </target>
+
+    <!-- add css, image, and js files for standalone snark to the war -->
+    <target name="standalone_war" depends="war">
+        <mkdir dir="build/standalone-resources/.resources/themes/snark" />
+        <copy todir="build/standalone-resources/.resources/themes/snark" >
+            <fileset dir="../../../installer/resources/themes/snark/" />
+        </copy>
+        <replace dir="build/standalone-resources/.resources/themes/snark"
+            summary="true"
+            token="url('/themes/"
+            value="url('/i2psnark/.resources/themes/" >
+            <include name="**/*.css" />
+        </replace>
+        <replace dir="build/standalone-resources/.resources/themes/snark"
+            summary="true"
+            token="url('../../console/images/"
+            value="url('/i2psnark/.resources/themes/snark/ubergine/images/" >
+            <include name="**/*.css" />
+        </replace>
+        <replace dir="build/standalone-resources/.resources/themes/snark"
+            summary="true"
+            token="url('../../console/dark/images/"
+            value="url('/i2psnark/.resources/themes/snark/ubergine/images/" >
+            <include name="**/*.css" />
+        </replace>
+        <replace dir="build/standalone-resources/.resources/themes/snark"
+            summary="true"
+            token="url('../../console/light/images/"
+            value="url('/i2psnark/.resources/themes/snark/ubergine/images/" >
+            <include name="**/*.css" />
+        </replace>
+        <replace dir="build/standalone-resources/.resources/themes/snark"
+            summary="true"
+            token="url('images/"
+            value="url('/i2psnark/.resources/themes/snark/ubergine/images/" >
+            <include name="**/*.css" />
+        </replace>
+        <copy todir="build/standalone-resources/.resources/themes/snark/ubergine/images" >
+            <!-- we really don't need all of these -->
+            <fileset dir="../../../installer/resources/themes/console/images/" />
+        </copy>
+        <copy file="../../../installer/resources/themes/console/dark/images/transparent.gif"
+              todir="build/standalone-resources/.resources/themes/snark/ubergine/images" />
+        <copy file="../../../installer/resources/themes/console/dark/images/header.png"
+              todir="build/standalone-resources/.resources/themes/snark/ubergine/images" />
+        <mkdir dir="build/standalone-resources/.resources/js" />
+        <copy file="../../routerconsole/jsp/js/ajax.js" todir="build/standalone-resources/.resources/js" />
+        <zip destfile="../i2psnark.war" update="true" duplicate="preserve" >
+            <fileset dir="build/standalone-resources" />
+        </zip>
+    </target>
+    
+    <target name="standalone_prep" depends="standalone_jar, standalone_war">
         <delete dir="./dist" />
         <mkdir dir="./dist" />
         <copy file="../launch-i2psnark" todir="./dist/" />
+        <mkdir dir="./dist/contexts" />
+        <!-- todo put in root context.xml -->
+        <mkdir dir="./dist/docroot" />
+        <!-- todo put in index.html to redirect -->
         <mkdir dir="./dist/webapps" />
         <copy file="../i2psnark.war" tofile="./dist/webapps/i2psnark.war" />
-        <mkdir dir="./dist/lib" />
-        <copy file="./build/i2psnark.jar" tofile="./dist/lib/i2psnark.jar" />
-        <copy file="../../../core/java/build/i2p.jar" tofile="./dist/lib/i2p.jar" />
-        <copy file="../../jetty/jettylib/commons-el.jar" tofile="./dist/lib/commons-el.jar" />
-        <copy file="../../jetty/jettylib/commons-logging.jar" tofile="./dist/lib/commons-logging.jar" />
-        <copy file="../../jetty/jettylib/javax.servlet.jar" tofile="./dist/lib/javax.servlet.jar" />
-        <copy file="../../jetty/jettylib/org.mortbay.jetty.jar" tofile="./dist/lib/org.mortbay.jetty.jar" />
-        <copy file="../../jetty/jettylib/jasper-runtime.jar" tofile="./dist/lib/jasper-runtime.jar" />
-        <copy file="../../ministreaming/java/build/mstreaming.jar" tofile="./dist/lib/mstreaming.jar" />
-        <copy file="../../streaming/java/build/streaming.jar" tofile="./dist/lib/streaming.jar" />
         <copy file="../jetty-i2psnark.xml" tofile="./dist/jetty-i2psnark.xml" />
+        <copy file="./build/i2psnark-standalone.jar" tofile="./dist/i2psnark.jar" />
         <copy file="../readme-standalone.txt" tofile="./dist/readme.txt" />
+        <!-- temp so announces work -->
+        <copy file="../../../installer/resources/hosts.txt" tofile="./dist/hosts.txt" />
+        <copy todir="./dist/licenses" >
+            <fileset dir="../../../licenses" includes="LICENSE-GPLv2.txt, ABOUT-Jetty.html" />
+        </copy>
         <mkdir dir="./dist/logs" />
-
-        <zip destfile="i2psnark-standalone.zip">
-         <zipfileset dir="./dist/" prefix="i2psnark/" />
-        </zip>
     </target>
 
     <target name="clean">
diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
index abfc32097854455a5c6f1b523ec8088d2f055afb..e9736fab874b6bd20b7b18c2e349c6aa8d6bc18d 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
@@ -233,6 +233,8 @@ public class SnarkManager implements CompleteListener {
         _configFile = new File(_configDir, CONFIG_FILE);
         _trackerMap = new ConcurrentHashMap<String, Tracker>(4);
         loadConfig(null);
+        if (!ctx.isRouterContext())
+            Runtime.getRuntime().addShutdownHook(new Thread(new TempDeleter(_util.getTempDir()), "Snark Temp Dir Deleter"));
     }
 
     /** Caller _must_ call loadConfig(file) before this if setting new values
@@ -245,7 +247,7 @@ public class SnarkManager implements CompleteListener {
         _monitor = new I2PAppThread(new DirMonitor(), "Snark DirMonitor", true);
         _monitor.start();
         // only if default instance
-        if ("i2psnark".equals(_contextName))
+        if (_context.isRouterContext() && "i2psnark".equals(_contextName))
             // delay until UpdateManager is there
             _context.simpleTimer2().addEvent(new Register(), 4*60*1000);
         // Not required, Jetty has a shutdown hook
@@ -254,6 +256,16 @@ public class SnarkManager implements CompleteListener {
         _idleChecker.schedule(5*60*1000);
     }
 
+    /**
+     * Only used in app context
+     * @since 0.9.27
+     */
+    private static class TempDeleter implements Runnable {
+        private final File file;
+        public TempDeleter(File f) { file = f; }
+        public void run() { FileUtil.rmdir(file, false); }
+    }
+
     /** @since 0.9.4 */
     private class Register implements SimpleTimer.TimedEvent {
         public void timeReached() {
@@ -388,6 +400,8 @@ public class SnarkManager implements CompleteListener {
     }
 
     private int getStartupDelayMinutes() { 
+        if (!_context.isRouterContext())
+            return 0;
         try {
 	    return Integer.parseInt(_config.getProperty(PROP_STARTUP_DELAY));
         } catch (NumberFormatException nfe) {
@@ -675,7 +689,8 @@ public class SnarkManager implements CompleteListener {
      * @return String[] -- Array of all the themes found, non-null, unsorted
      */
     public String[] getThemes() {
-            String[] themes;
+         String[] themes;
+         if (_context.isRouterContext()) {
             // "docs/themes/snark/"
             File dir = new File(_context.getBaseDir(), "docs/themes/snark");
             FileFilter fileFilter = new FileFilter() { public boolean accept(File file) { return file.isDirectory(); } };
@@ -689,8 +704,10 @@ public class SnarkManager implements CompleteListener {
             } else {
                 themes = new String[0];
             }
-            // return the map.
-            return themes;
+        } else {
+            themes = new String[] { "light", "ubergine", "vanilla" };
+        }
+        return themes;
     }
 
 
@@ -815,7 +832,7 @@ public class SnarkManager implements CompleteListener {
             }
         }
         
-	if (startDelay != null){
+	if (startDelay != null && _context.isRouterContext()) {
 		int minutes = _util.getStartupDelay();
                 try { minutes = Integer.parseInt(startDelay.trim()); } catch (NumberFormatException nfe) {}
 	        if ( minutes != _util.getStartupDelay()) {
diff --git a/apps/i2psnark/java/src/org/klomp/snark/standalone/RunStandalone.java b/apps/i2psnark/java/src/org/klomp/snark/standalone/RunStandalone.java
new file mode 100644
index 0000000000000000000000000000000000000000..521d0ec58bcb3713c34834caf4fc5fed33ba901f
--- /dev/null
+++ b/apps/i2psnark/java/src/org/klomp/snark/standalone/RunStandalone.java
@@ -0,0 +1,62 @@
+package org.klomp.snark.standalone;
+
+import java.io.File;
+
+import net.i2p.I2PAppContext;
+import net.i2p.apps.systray.UrlLauncher;
+import net.i2p.jetty.JettyStart;
+
+/**
+ *  @since moved from ../web and fixed in 0.9.27
+ */
+public class RunStandalone {
+    
+    private final JettyStart _jettyStart;
+    private final I2PAppContext _context;
+    private int _port = 8002;
+    private String _host = "127.0.0.1";
+
+    private RunStandalone(String args[]) throws Exception {
+        _context = I2PAppContext.getGlobalContext();
+        File base = _context.getBaseDir();
+        File xml = new File(base, "jetty-i2psnark.xml");
+        _jettyStart = new JettyStart(_context, null, new String[] { xml.getAbsolutePath() } );
+        if (args.length > 1) {
+            _port = Integer.parseInt(args[1]);
+        } 
+        if (args.length > 0) {
+            _host = args[0];
+        }
+    }
+    
+    /**
+     *  Usage: RunStandalone [host [port]] (but must match what's in the jetty-i2psnark.xml file)
+     */
+    public static void main(String args[]) {
+        try {
+            RunStandalone runner = new RunStandalone(args);
+            runner.start();
+        } catch (Exception e) {
+            e.printStackTrace();
+            System.exit(1);
+        }
+    }
+    
+    public void start() {
+        try {
+            _jettyStart.startup();
+            String url = "http://" + _host + ':' + _port + "/i2psnark/";
+            try {
+               Thread.sleep(1000);
+            } catch (InterruptedException ie) {}
+            UrlLauncher launch = new UrlLauncher(_context, null, new String[] { url } );
+            launch.startup();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+    
+    public void stop() {
+        _jettyStart.shutdown(null);
+    }
+}
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
index 74688f2c726d8fa2a9db497c6681c21920710db5..fd914e27bc1d349ab326a96145a60e6a94da5319 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -4,7 +4,6 @@ import java.io.File;
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.Serializable;
-import java.text.Collator;
 import java.text.DecimalFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
@@ -192,7 +191,10 @@ public class I2PSnarkServlet extends BasicServlet {
             return;
         }
 
-        _themePath = "/themes/snark/" + _manager.getTheme() + '/';
+        if (_context.isRouterContext())
+            _themePath = "/themes/snark/" + _manager.getTheme() + '/';
+        else
+            _themePath = _contextPath + WARBASE + "themes/snark/" + _manager.getTheme() + '/';
         _imgPath = _themePath + "images/";
         req.setCharacterEncoding("UTF-8");
 
@@ -285,8 +287,9 @@ public class I2PSnarkServlet extends BasicServlet {
         if (!isConfigure) {
             delay = _manager.getRefreshDelaySeconds();
             if (delay > 0) {
+                String jsPfx = _context.isRouterContext() ? "" : ".resources";
                 //out.write("<meta http-equiv=\"refresh\" content=\"" + delay + ";/i2psnark/" + peerString + "\">\n");
-                out.write("<script src=\"/js/ajax.js\" type=\"text/javascript\"></script>\n" +
+                out.write("<script src=\"" + jsPfx + "/js/ajax.js\" type=\"text/javascript\"></script>\n" +
                           "<script type=\"text/javascript\">\n"  +
                           "var failMessage = \"<div class=\\\"routerdown\\\"><b>" + _t("Router is down") + "<\\/b><\\/div>\";\n" +
                           "function requestAjax1() { ajax(\"" + _contextPath + "/.ajax/xhr1.html" +
@@ -324,17 +327,19 @@ public class I2PSnarkServlet extends BasicServlet {
                 out.write(_t("I2PSnark"));
             else
                 out.write(_contextName);
-            out.write("</a> <a href=\"http://forum.i2p/viewforum.php?f=21\" class=\"snarkRefresh\" target=\"_blank\">");
-            out.write(_t("Forum"));
             out.write("</a>\n");
-
             sortedTrackers = _manager.getSortedTrackers();
-            for (Tracker t : sortedTrackers) {
-                if (t.baseURL == null || !t.baseURL.startsWith("http"))
-                    continue;
-                if (_manager.util().isKnownOpenTracker(t.announceURL))
-                    continue;
-                out.write(" <a href=\"" + t.baseURL + "\" class=\"snarkRefresh\" target=\"_blank\">" + t.name + "</a>");
+            if (_context.isRouterContext()) {
+                out.write("<a href=\"http://forum.i2p/viewforum.php?f=21\" class=\"snarkRefresh\" target=\"_blank\">");
+                out.write(_t("Forum"));
+                out.write("</a>\n");
+                for (Tracker t : sortedTrackers) {
+                    if (t.baseURL == null || !t.baseURL.startsWith("http"))
+                        continue;
+                    if (_manager.util().isKnownOpenTracker(t.announceURL))
+                        continue;
+                    out.write(" <a href=\"" + t.baseURL + "\" class=\"snarkRefresh\" target=\"_blank\">" + t.name + "</a>");
+                }
             }
         }
         out.write("</div>\n");
@@ -2229,12 +2234,14 @@ public class I2PSnarkServlet extends BasicServlet {
         out.write("</select><br>" +
 
                   "<tr><td>");
-        out.write(_t("Startup delay"));
-        out.write(": <td><input name=\"startupDelay\" size=\"4\" class=\"r\" value=\"" + _manager.util().getStartupDelay() + "\"> ");
-        out.write(_t("minutes"));
-        out.write("<br>\n" +
+        if (_context.isRouterContext()) {
+            out.write(_t("Startup delay"));
+            out.write(": <td><input name=\"startupDelay\" size=\"4\" class=\"r\" value=\"" + _manager.util().getStartupDelay() + "\"> ");
+            out.write(_t("minutes"));
+            out.write("<br>\n" +
 
-                  "<tr><td>");
+                      "<tr><td>");
+        }
         out.write(_t("Page size"));
         out.write(": <td><input name=\"pageSize\" size=\"4\" maxlength=\"6\" class=\"r\" value=\"" + _manager.getPageSize() + "\"> ");
         out.write(_t("torrents"));
diff --git a/apps/i2psnark/java/src/org/klomp/snark/web/RunStandalone.java b/apps/i2psnark/java/src/org/klomp/snark/web/RunStandalone.java
deleted file mode 100644
index 0104d7dcbefd8f9ff2db0be86c643132dd23dfe2..0000000000000000000000000000000000000000
--- a/apps/i2psnark/java/src/org/klomp/snark/web/RunStandalone.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package org.klomp.snark.web;
-
-import java.io.File;
-
-import net.i2p.I2PAppContext;
-import net.i2p.util.FileUtil;
-
-//import org.eclipse.jetty.server.Server;
-
-/**
- *  @deprecated does not work
- */
-@Deprecated
-public class RunStandalone {
-/****
-    static {
-        System.setProperty("org.mortbay.http.Version.paranoid", "true");
-        System.setProperty("org.mortbay.xml.XmlParser.NotValidating", "true");
-    }
-****/
-    
-    private RunStandalone(String args[]) {}
-    
-    public static void main(String args[]) {
-        RunStandalone runner = new RunStandalone(args);
-        runner.start();
-    }
-    
-    public void start() {
-        throw new RuntimeException("unsupported");
-/****
-        File workDir = new File(I2PAppContext.getGlobalContext().getTempDir(), "jetty-work");
-        boolean workDirRemoved = FileUtil.rmdir(workDir, false);
-        if (!workDirRemoved)
-            System.err.println("ERROR: Unable to remove Jetty temporary work directory");
-        boolean workDirCreated = workDir.mkdirs();
-        if (!workDirCreated)
-            System.err.println("ERROR: Unable to create Jetty temporary work directory");
-        
-        try {
-            _server = new Server("jetty-i2psnark.xml");
-            // just blow up NPE if we don't have a context
-            (_server.getContexts()[0]).setTempDirectory(workDir);
-            _server.start();
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-****/
-    }
-    
-    public void stop() {
-        throw new RuntimeException("unsupported");
-/****
-        try {
-            _server.stop();
-        } catch (InterruptedException ie) {
-            ie.printStackTrace();
-        }
-****/
-    }
-}
diff --git a/apps/i2psnark/jetty-i2psnark.xml b/apps/i2psnark/jetty-i2psnark.xml
index b5d6d1ef8f0616fca46b53ddd49f7893a0205faf..53d0e15e92bc0a26e5ab6dd9561e47eae0930b6b 100644
--- a/apps/i2psnark/jetty-i2psnark.xml
+++ b/apps/i2psnark/jetty-i2psnark.xml
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="ISO-8859-1" ?> 
-<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure 1.2//EN" "http://jetty.mortbay.org/configure_1_2.dtd">
+<?xml version="1.0" encoding="UTF-8" ?> 
+<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
 
 <!-- =============================================================== -->
 <!-- This is the configuration for a standalone i2psnark and         -->
@@ -11,7 +11,7 @@
 <!-- =============================================================== -->
 <!-- Configure the Jetty Server                                      -->
 <!-- =============================================================== -->
-<Configure class="org.mortbay.jetty.Server">
+<Configure id="Server" class="org.eclipse.jetty.server.Server">
 
   <!-- =============================================================== -->
   <!-- Configure the Request Listeners                                 -->
@@ -20,23 +20,18 @@
   <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
   <!-- Add and configure a HTTP listener to port 8002                  -->
   <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-  <Call name="addListener">
+  <Call name="addConnector">
     <Arg>
-      <New class="org.mortbay.http.SocketListener">
-        <Arg>
-          <New class="org.mortbay.util.InetAddrPort">
-            <Set name="host">127.0.0.1</Set>
-            <Set name="port">8002</Set>
-          </New>
-        </Arg>
-        <Set name="MinThreads">1</Set>
-        <Set name="MaxThreads">10</Set>
-        <Set name="MaxIdleTimeMs">30000</Set>
-        <Set name="LowResourcePersistTimeMs">1000</Set>
-        <Set name="ConfidentialPort">8443</Set>
-        <Set name="IntegralPort">8443</Set>
-        <Set name="PoolName">main</Set>
-      </New>
+        <New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
+          <Set name="host">127.0.0.1</Set>
+          <Set name="port">8002</Set>
+          <Set name="maxIdleTime">600000</Set>
+          <Set name="Acceptors">1</Set>
+          <Set name="statsOn">false</Set>
+          <Set name="lowResourcesConnections">5000</Set>
+          <Set name="lowResourcesMaxIdleTime">5000</Set>
+          <Set name="useDirectBuffers">false</Set>
+        </New>
     </Arg>
   </Call>
 
@@ -44,41 +39,103 @@
   <!-- Configure the Contexts                                          -->
   <!-- =============================================================== -->
 
+    <!-- =========================================================== -->
+    <!-- Set handler Collection Structure                            --> 
+    <!-- =========================================================== -->
+    <Set name="handler">
+      <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
+        <Set name="handlers">
+         <Array type="org.eclipse.jetty.server.Handler">
+           <Item>
+             <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
+           </Item>
+           <Item>
+             <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
+           </Item>
+         </Array>
+        </Set>
+      </New>
+    </Set>
 
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-  <!-- Add a all web application within the webapps directory.         -->
-  <!-- + No virtual host specified                                     -->
-  <!-- + Look in the webapps directory relative to jetty.home or .     -->
-  <!-- + Use the default webdefault.xml in jetty's install             -->
-  <!-- + Upack the war file                                            -->
-  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
-  <Set name="rootWebApp">i2psnark</Set>
-  <Call name="addWebApplication">
-    <Arg>/</Arg>
-    <Arg>webapps/i2psnark.war</Arg>
-  </Call>
+    <!-- =============================================================== -->
+    <!-- Create the deployment manager                                   -->
+    <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
+    <!-- The deplyment manager handles the lifecycle of deploying web    -->
+    <!-- applications. Apps are provided by instances of the             -->
+    <!-- AppProvider interface.  Typically these are provided by         -->
+    <!-- one or more of:                                                 -->
+    <!--   jetty-webapps.xml       - monitors webapps for wars and dirs  -->
+    <!--   jetty-contexts.xml      - monitors contexts for context xml   -->
+    <!--   jetty-templates.xml     - monitors contexts and templates     -->
+    <!-- =============================================================== -->
+    <Call name="addBean">
+      <Arg>
+        <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
+          <Set name="contexts">
+            <Ref id="Contexts" />
+          </Set>
+          <Call name="setContextAttribute">
+            <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
+            <Arg>.*/.*jsp-api-[^/]*\.jar$|.*/.*jsp-[^/]*\.jar$|.*/.*taglibs[^/]*\.jar$</Arg>
+          </Call>
+        </New>
+      </Arg>
+    </Call>
 
-  <!-- this is so we can find the css -->
-  <Call name="addContext">
-    <Arg>
-      <New class="org.mortbay.http.HttpContext">
-        <Set name="contextPath">/themes</Set>
-        <Set name="resourceBase">./docs/themes</Set>
-        <Call name="addHandler">
-          <Arg>
-            <New class="org.mortbay.http.handler.ResourceHandler">
-              <Set name="redirectWelcome">FALSE</Set>
-	    </New>
-          </Arg>
-        </Call>
-      </New>
-    </Arg>
-  </Call>
-  
-  <!-- =============================================================== -->
-  <!-- Configure the Other Server Options                              -->
-  <!-- =============================================================== -->
-  <Set name="requestsPerGC">2000</Set>
-  <Set name="statsOn">false</Set>
+    <!-- =========================================================== -->
+    <!-- Configure the context deployer                              -->
+    <!-- A context deployer will deploy contexts described in        -->
+    <!-- configuration files discovered in a directory.              -->
+    <!-- The configuration directory can be scanned for hot          -->
+    <!-- deployments at the configured scanInterval.                 -->
+    <!--                                                             -->
+    <!-- This deployer is configured to deploy contexts configured   -->
+    <!-- in the $JETTY_HOME/contexts directory                       -->
+    <!--                                                             -->
+    <!-- =========================================================== -->
+    <Ref id="DeploymentManager">
+      <Call name="addAppProvider">
+        <Arg>
+          <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
+            <Set name="monitoredDirName">./contexts</Set>
+            <Set name="scanInterval">0</Set>
+          </New>
+        </Arg>
+      </Call>
+    </Ref>
+
+    <!-- =========================================================== -->
+    <!-- Configure the webapp deployer.                              -->
+    <!-- A webapp  deployer will deploy standard webapps discovered  -->
+    <!-- in a directory at startup, without the need for additional  -->
+    <!-- configuration files.    It does not support hot deploy or   -->
+    <!-- non standard contexts (see ContextDeployer above).          -->
+    <!--                                                             -->
+    <!-- This deployer is configured to deploy webapps from the      -->
+    <!-- $JETTY_HOME/webapps directory                               -->
+    <!--                                                             -->
+    <!-- Normally only one type of deployer need be used.            -->
+    <!--                                                             -->
+    <!-- =========================================================== -->
+    <Ref id="DeploymentManager">
+      <Call id="webappprovider" name="addAppProvider">
+        <Arg>
+          <New class="org.eclipse.jetty.deploy.providers.WebAppProvider">
+            <Set name="monitoredDirName">./webapps</Set>
+	    <Set name="parentLoaderPriority">false</Set>
+	    <Set name="extractWars">false</Set>
+            <Set name="scanInterval">0</Set>
+          </New>
+        </Arg>
+      </Call>
+    </Ref>
+
+    <!-- ===================== -->
+    <!-- DefaultHandler config -->
+    <!-- http://stackoverflow.com/questions/4202275/how-to-prevent-jetty-from-showing-context-related-information -->
+    <!-- ===================== -->
+    <Ref id="DefaultHandler">
+      <Set name="showContexts">false</Set>
+    </Ref>
 
 </Configure>
diff --git a/apps/i2psnark/launch-i2psnark b/apps/i2psnark/launch-i2psnark
index 023b5a21a7c1d0c8d3c16e752b4ae9e134b333d3..4f89c4c8cc05a0627677a4aca5fdb9110c140027 100755
--- a/apps/i2psnark/launch-i2psnark
+++ b/apps/i2psnark/launch-i2psnark
@@ -5,4 +5,4 @@
 # i2psnark will be accessed at http://127.0.0.1:8002/
 #
 I2P="."
-java -cp "$I2P/lib/i2psnark.jar:$I2P/lib/i2p.jar:$I2P/lib/mstreaming.jar:$I2P/lib/streaming.jar:$I2P/lib/commons-el.jar:$I2P/lib/commons-logging.jar:$I2P/lib/jasper-compiler.jar:$I2P/lib/jasper-runtime.jar:$I2P/lib/javax.servlet.jar:$I2P/lib/org.mortbay.jetty.jar" org.klomp.snark.web.RunStandalone "$@"
+java -jar "$I2P/i2psnark.jar"
diff --git a/apps/i2psnark/readme-standalone.txt b/apps/i2psnark/readme-standalone.txt
index ced04e941f393be0e0ce10a9dfa2a4027d25537d..fa35c65ee5287097f8fdf31c84924cc75ad643ab 100644
--- a/apps/i2psnark/readme-standalone.txt
+++ b/apps/i2psnark/readme-standalone.txt
@@ -1,4 +1,12 @@
-i2psnark is packaged as a webapp running in the router console.
-Command line and standalone operation of i2psnark are not currently supported.
-See http://trac.i2p2.i2p/ticket/1191 or http://trac.i2p2.de/ticket/1191
-for the status of restoring standalone support.
+To run i2psnark's standalone mode make sure you have an i2p router running in the background, then run:
+
+java -jar i2psnark.jar
+
+I2PSnark web ui will be at http://127.0.0.1:8002/i2psnark/ 
+
+Please note that http://127.0.0.1:8002/ will 404, to be fixed
+
+I2PSnark is GPL'ed software, based on Snark (http://www.klomp.org/) to run on top of I2P
+(https://geti2p.net/) within a webserver (such as the bundled Jetty from
+https://www.eclipse.org/jetty/).  For more information about I2PSnark, get in touch
+with the folks at http://forum.i2p2.de/
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java
index 99d225a348cd8e922e82e9d62653844ede3f1b57..fc9ecebfd706087e6644945a5cbf7431ecc0a7c4 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnel.java
@@ -1338,7 +1338,6 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
             }
             if (i < args.length) {
                 host = args[i++];
-                listenHost = host;
             }
             if (i < args.length)
                 port = args[i];
diff --git a/build.xml b/build.xml
index 5e3a03f86c6783d930fe6d094e93077759b9740d..0a9c942aae409f4db3639e8b6ae8126a01d4cba6 100644
--- a/build.xml
+++ b/build.xml
@@ -301,7 +301,7 @@
         <copy file="apps/imagegen/imagegen/build/imagegen.war" todir="build/" />
     </target>
 
-    <target name="buildI2PSnark" depends="buildStreaming, buildJetty" >
+    <target name="buildI2PSnark" depends="buildStreaming, buildJetty, buildSystray" >
         <ant dir="apps/i2psnark/java/" target="war" />
         <copy file="apps/i2psnark/i2psnark.war" todir="build/" />
         <copy file="apps/i2psnark/java/build/i2psnark.jar" todir="build/" />
@@ -325,7 +325,7 @@
         <copy file="apps/i2ptunnel/java/build/i2ptunnel-ui.jar" todir="build/" />
     </target>
 
-    <target name="buildI2PTunnel" depends="buildStreaming, buildJetty" >
+    <target name="buildI2PTunnel" depends="buildStreaming, buildJetty, buildImagegen" >
         <ant dir="apps/i2ptunnel/java/" target="build" />
         <copy file="apps/i2ptunnel/java/build/i2ptunnel.jar" todir="build/" />
         <copy file="apps/i2ptunnel/java/build/i2ptunnel.war" todir="build/" />
@@ -1809,10 +1809,13 @@
         <ant dir="apps/syndie/java/" target="standalone" />
         <copy file="apps/syndie/java/syndie-standalone.zip" todir="." />
     </target> -->
-    <target name="i2psnark" depends="buildProperties" >
+
+    <!-- standalone i2psnark zip -->
+    <target name="i2psnark" depends="buildStreaming, buildJetty, buildSystray" >
         <ant dir="apps/i2psnark/java" target="standalone" />
         <copy file="apps/i2psnark/java/i2psnark-standalone.zip" todir="." />
     </target>
+
     <target name="slackpkg">
         <ant dir="Slackware/i2p/" target="slackpkg" />
     </target>
diff --git a/core/c/jbigi/jbigi/src/jbigi.c b/core/c/jbigi/jbigi/src/jbigi.c
index a9c5db5447d1c6e1249d88bd573bc2772778dfdc..dda0a5f6ab9a5cebcf9f2690dbb678f498f86ffe 100644
--- a/core/c/jbigi/jbigi/src/jbigi.c
+++ b/core/c/jbigi/jbigi/src/jbigi.c
@@ -1,4 +1,5 @@
 #include <stdio.h>
+#include <string.h>
 #include <gmp.h>
 #include "jbigi.h"
 
@@ -15,7 +16,7 @@ void convert_mp2j(JNIEnv* env, mpz_t mvalue, jbyteArray* jvalue);
  * 2: (I2P 0.8.7)
  *    Removed nativeDoubleValue()
  *
- * 3: (I2P 0.9.18)
+ * 3: (I2P 0.9.26)
  *    Added:
  *      nativeJbigiVersion()
  *      nativeGMPMajorVersion()
@@ -26,8 +27,12 @@ void convert_mp2j(JNIEnv* env, mpz_t mvalue, jbyteArray* jvalue);
  *    Support negative base value in modPow()
  *    Throw ArithmeticException for bad arguments in modPow()
  *
+ * 4: (I2P 0.9.27)
+ *    Fix nativeGMPMajorVersion(), nativeGMPMinorVersion(), and nativeGMPPatchVersion()
+ *    when built as a shared library
+ *
  */
-#define JBIGI_VERSION 3
+#define JBIGI_VERSION 4
 
 /*****************************************
  *****Native method implementations*******
@@ -39,22 +44,31 @@ JNIEXPORT jint JNICALL Java_net_i2p_util_NativeBigInteger_nativeJbigiVersion
     return (jint) JBIGI_VERSION;
 }
 
-/* since version 3 */
+/* since version 3, fixed for dynamic builds in version 4 */
 JNIEXPORT jint JNICALL Java_net_i2p_util_NativeBigInteger_nativeGMPMajorVersion
         (JNIEnv* env, jclass cls) {
-    return (jint) __GNU_MP_VERSION;
+    int v = gmp_version[0] - '0';
+    return (jint) v;
 }
 
-/* since version 3 */
+/* since version 3, fixed for dynamic builds in version 4 */
 JNIEXPORT jint JNICALL Java_net_i2p_util_NativeBigInteger_nativeGMPMinorVersion
         (JNIEnv* env, jclass cls) {
-    return (jint) __GNU_MP_VERSION_MINOR;
+    int v = 0;
+    if (strlen(gmp_version) > 2) {
+        v = gmp_version[2] - '0';
+    }
+    return (jint) v;
 }
 
-/* since version 3 */
+/* since version 3, fixed for dynamic builds in version 4 */
 JNIEXPORT jint JNICALL Java_net_i2p_util_NativeBigInteger_nativeGMPPatchVersion
         (JNIEnv* env, jclass cls) {
-    return (jint) __GNU_MP_VERSION_PATCHLEVEL;
+    int v = 0;
+    if (strlen(gmp_version) > 4) {
+        v = gmp_version[4] - '0';
+    }
+    return (jint) v;
 }
 
 /******** nativeModPow() */
diff --git a/core/c/jbigi/mbuild-all.sh b/core/c/jbigi/mbuild-all.sh
index be3072ac8bb4ac33b695d591f0e10d1c49c2dab6..8c2b1d89e1e94e3606fa31ce1687f8696edff50a 100755
--- a/core/c/jbigi/mbuild-all.sh
+++ b/core/c/jbigi/mbuild-all.sh
@@ -79,34 +79,32 @@ if [ ! -f "$JAVA_HOME/include/jni.h" ]; then
 fi
 
 if ! command -v m4 > /dev/null; then
-    printf "\aWARNING: \`m4\` not found. If this process fails to complete, install m4 " >&2
+    printf "\aWARNING: \`m4\` not found. Install m4 " >&2
     printf "and re-run this script.\n\n\n\a" >&2
     exit 1
 fi
 
 
 if [ -z $BITS ]; then
-  UNAME="$(uname -a)"
-  if test "${UNAME#*x86_64}" != "x86_&4"; then
+  UNAME="$(uname -m)"
+  if test "${UNAME#*x86_64}" != "$UNAME"; then
     BITS=64
-  elif test "${UNAME#*i386}" != "i386"; then
+  elif test "${UNAME#*i386}" != "$UNAME"; then
     BITS=32
-  elif test "${UNAME#*i686}" != "i686"; then
+  elif test "${UNAME#*i686}" != "$UNAME"; then
     BITS=32
-  elif test "${UNAME#*armv6}" != "armv6"; then
+  elif test "${UNAME#*armv6}" != "$UNAME"; then
     BITS=32
-  elif test "${UNAME#*armv7}" != "armv7"; then
+  elif test "${UNAME#*armv7}" != "$UNAME"; then
     BITS=32
-  elif test "${UNAME#*aarch32}" != "aarch32"; then
+  elif test "${UNAME#*aarch32}" != "$UNAME"; then
     BITS=32
-  elif test "${UNAME#*aarch64}" != "aarch64"; then
+  elif test "${UNAME#*aarch64}" != "$UNAME"; then
     BITS=64
   else
- 
     echo "Unable to detect default setting for BITS variable"
-    exit
+    exit 1
   fi
-
   printf "\aBITS variable not set, $BITS bit system detected\n\a" >&2
 fi
 
@@ -116,6 +114,7 @@ if [ -z $CC ]; then
   printf "\aCC variable not set, defaulting to $CC\n\a" >&2
 fi
 
+# FIXME -m32 and -m64 are only for x86
 if [ $BITS -eq 32 ]; then
   export ABI=32
   export CFLAGS="-m32"
diff --git a/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java b/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java
index 5cb6772739941828598c65d399d159cd58979648..4b4b0ec6819e382d3897e8b4097c05a1df959f4b 100644
--- a/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java
+++ b/core/java/src/freenet/support/CPUInformation/AMDCPUInfo.java
@@ -41,6 +41,7 @@ public interface AMDCPUInfo extends CPUInfo {
     public boolean IsAthlon64Compatible();
     /** 
      * @return true if the CPU present in the machine is at least an 'k10' CPU
+     * @since 0.9.26
      */
     public boolean IsK10Compatible();
     /**
@@ -49,6 +50,7 @@ public interface AMDCPUInfo extends CPUInfo {
 	public boolean IsBobcatCompatible();
     /**
      * @return true if the CPU present in the machine is at least an 'jaguar' CPU
+     * @since 0.9.26
      */
 	public boolean IsJaguarCompatible();
     /**
@@ -57,14 +59,17 @@ public interface AMDCPUInfo extends CPUInfo {
 	public boolean IsBulldozerCompatible();
     /**
      * @return true if the CPU present in the machine is at least a 'piledriver' CPU
+     * @since 0.9.26
      */
 	public boolean IsPiledriverCompatible();
     /**
      * @return true if the CPU present in the machine is at least a 'steamroller' CPU
+     * @since 0.9.26
      */
 	public boolean IsSteamrollerCompatible();
     /**
      * @return true if the CPU present in the machine is at least a 'excavator' CPU
+     * @since 0.9.26
      */
 	public boolean IsExcavatorCompatible();
 
diff --git a/core/java/src/freenet/support/CPUInformation/CPUID.java b/core/java/src/freenet/support/CPUInformation/CPUID.java
index d23f4f23bb3382ac3c7f0ff7e8333c9a7b13c7a5..5bd79d0ae76abee0fd1466a0fb4f1a4f5755b95c 100644
--- a/core/java/src/freenet/support/CPUInformation/CPUID.java
+++ b/core/java/src/freenet/support/CPUInformation/CPUID.java
@@ -376,27 +376,33 @@ public class CPUID {
         System.out.println("CPU has ABM:    " + c.hasABM());
         if(c instanceof IntelCPUInfo){
             System.out.println("\n **Intel-info**");
-            System.out.println("Is PII-compatible: "+((IntelCPUInfo)c).IsPentium2Compatible());
-            System.out.println("Is PIII-compatible: "+((IntelCPUInfo)c).IsPentium3Compatible());
-            System.out.println("Is PIV-compatible: "+((IntelCPUInfo)c).IsPentium4Compatible());
-            System.out.println("Is Atom-compatible: "+((IntelCPUInfo)c).IsAtomCompatible());
+            System.out.println("Is PII-compatible:       "+((IntelCPUInfo)c).IsPentium2Compatible());
+            System.out.println("Is PIII-compatible:      "+((IntelCPUInfo)c).IsPentium3Compatible());
+            System.out.println("Is PIV-compatible:       "+((IntelCPUInfo)c).IsPentium4Compatible());
+            System.out.println("Is Atom-compatible:      "+((IntelCPUInfo)c).IsAtomCompatible());
             System.out.println("Is Pentium M compatible: "+((IntelCPUInfo)c).IsPentiumMCompatible());
-            System.out.println("Is Core2-compatible: "+((IntelCPUInfo)c).IsCore2Compatible());
-            System.out.println("Is Corei-compatible: "+((IntelCPUInfo)c).IsCoreiCompatible());
-            System.out.println("Is Sandy-compatible: "+((IntelCPUInfo)c).IsSandyCompatible());
-            System.out.println("Is Ivy-compatible: "+((IntelCPUInfo)c).IsIvyCompatible());
-            System.out.println("Is Haswell-compatible: "+((IntelCPUInfo)c).IsHaswellCompatible());
+            System.out.println("Is Core2-compatible:     "+((IntelCPUInfo)c).IsCore2Compatible());
+            System.out.println("Is Corei-compatible:     "+((IntelCPUInfo)c).IsCoreiCompatible());
+            System.out.println("Is Sandy-compatible:     "+((IntelCPUInfo)c).IsSandyCompatible());
+            System.out.println("Is Ivy-compatible:       "+((IntelCPUInfo)c).IsIvyCompatible());
+            System.out.println("Is Haswell-compatible:   "+((IntelCPUInfo)c).IsHaswellCompatible());
             System.out.println("Is Broadwell-compatible: "+((IntelCPUInfo)c).IsBroadwellCompatible());
         }
         if(c instanceof AMDCPUInfo){
             System.out.println("\n **AMD-info**");
-            System.out.println("Is K6-compatible: "+((AMDCPUInfo)c).IsK6Compatible());
-            System.out.println("Is K6_2-compatible: "+((AMDCPUInfo)c).IsK6_2_Compatible());
-            System.out.println("Is K6_3-compatible: "+((AMDCPUInfo)c).IsK6_3_Compatible());
-            System.out.println("Is Geode-compatible: "+((AMDCPUInfo)c).IsGeodeCompatible());
-            System.out.println("Is Athlon-compatible: "+((AMDCPUInfo)c).IsAthlonCompatible());
-            System.out.println("Is Athlon64-compatible: "+((AMDCPUInfo)c).IsAthlon64Compatible());
-            System.out.println("Is Bobcat-compatible: "+((AMDCPUInfo)c).IsBobcatCompatible());
+            System.out.println("Is K6-compatible:          "+((AMDCPUInfo)c).IsK6Compatible());
+            System.out.println("Is K6_2-compatible:        "+((AMDCPUInfo)c).IsK6_2_Compatible());
+            System.out.println("Is K6_3-compatible:        "+((AMDCPUInfo)c).IsK6_3_Compatible());
+            System.out.println("Is Geode-compatible:       "+((AMDCPUInfo)c).IsGeodeCompatible());
+            System.out.println("Is Athlon-compatible:      "+((AMDCPUInfo)c).IsAthlonCompatible());
+            System.out.println("Is Athlon64-compatible:    "+((AMDCPUInfo)c).IsAthlon64Compatible());
+            System.out.println("Is Bobcat-compatible:      "+((AMDCPUInfo)c).IsBobcatCompatible());
+            System.out.println("Is K10-compatible:         "+((AMDCPUInfo)c).IsK10Compatible());
+            System.out.println("Is Jaguar-compatible:      "+((AMDCPUInfo)c).IsJaguarCompatible());
+            System.out.println("Is Bulldozer-compatible:   "+((AMDCPUInfo)c).IsBulldozerCompatible());
+            System.out.println("Is Piledriver-compatible:  "+((AMDCPUInfo)c).IsPiledriverCompatible());
+            System.out.println("Is Steamroller-compatible: "+((AMDCPUInfo)c).IsSteamrollerCompatible());
+            System.out.println("Is Excavator-compatible:   "+((AMDCPUInfo)c).IsExcavatorCompatible());
         }
     }
 
diff --git a/core/java/src/net/i2p/crypto/KeyGenerator.java b/core/java/src/net/i2p/crypto/KeyGenerator.java
index 4297fcae20faa36e79a283378b5fff1d72431510..6a087c50a942c79e269b54aea4d542381fd459a9 100644
--- a/core/java/src/net/i2p/crypto/KeyGenerator.java
+++ b/core/java/src/net/i2p/crypto/KeyGenerator.java
@@ -15,6 +15,7 @@ import java.security.InvalidKeyException;
 import java.security.KeyFactory;
 import java.security.KeyPair;
 import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
 import java.security.ProviderException;
 import java.security.interfaces.ECPrivateKey;
 import java.security.interfaces.ECPublicKey;
@@ -416,19 +417,30 @@ public final class KeyGenerator {
         else
             System.out.println(type + " private-to-public test FAILED");
         //System.out.println("privkey " + keys[1]);
+          MessageDigest md = type.getDigestInstance();
         for (int i = 0; i < runs; i++) {
             RandomSource.getInstance().nextBytes(src);
+              md.update(src);
+              byte[] sha = md.digest();
+              SimpleDataStructure hash = type.getHashInstance();
+              hash.setData(sha);
             long start = System.nanoTime();
             Signature sig = DSAEngine.getInstance().sign(src, privkey);
+            Signature sig2 = DSAEngine.getInstance().sign(hash, privkey);
             if (sig == null)
                 throw new GeneralSecurityException("signature generation failed");
+            if (sig2 == null)
+                throw new GeneralSecurityException("signature generation (H) failed");
             long mid = System.nanoTime();
             boolean ok = DSAEngine.getInstance().verifySignature(sig, src, pubkey);
+            boolean ok2 = DSAEngine.getInstance().verifySignature(sig2, hash, pubkey);
             long end = System.nanoTime();
             stime += mid - start;
             vtime += end - mid;
             if (!ok)
                 throw new GeneralSecurityException(type + " V(S(data)) fail");
+            if (!ok2)
+                throw new GeneralSecurityException(type + " V(S(H(data))) fail");
         }
         stime /= 1000*1000;
         vtime /= 1000*1000;
diff --git a/installer/resources/themes/snark/light/snark.css b/installer/resources/themes/snark/light/snark.css
index c195775c06038574fe94657eb831bebd0f4bceb4..a02f899686b02d42ea94ab2c88be6cb28f296544 100644
--- a/installer/resources/themes/snark/light/snark.css
+++ b/installer/resources/themes/snark/light/snark.css
@@ -29,7 +29,7 @@ body.iframed {
      font-weight: bold;
      font-size: 9pt;
      color: #559;
-     background: #fff url("../../console/light/images/header.png") repeat-x scroll center center;
+     background: #fff url('../../console/light/images/header.png') repeat-x scroll center center;
      -moz-border-radius: 0px;
      -khtml-border-radius: 3px;
      border-radius: 0px;
@@ -167,7 +167,7 @@ th {
      border-bottom: 1px solid #66f;
      color: #001;
       whitespace: nowrap;
-     background: #fff url("../../console/light/images/header.png") repeat-x scroll center center;
+     background: #fff url('../../console/light/images/header.png') repeat-x scroll center center;
 }
 
 th:first-child {
@@ -414,7 +414,7 @@ td:first-child {
      border-radius: 0 0 5px 5px;
      border-top: 0;
      text-shadow: 0 1px 0 #aaa;
-     background: #fff url("../../console/light/images/header.png") repeat-x scroll center center;
+     background: #fff url('../../console/light/images/header.png') repeat-x scroll center center;
      font-variant: small-caps !important;
      box-shadow: 0 1px 3px #999;
 }
diff --git a/installer/resources/themes/snark/vanilla/snark.css b/installer/resources/themes/snark/vanilla/snark.css
index b5ab1155b3ae2953942472170d0de4c24b5f2c76..382d6aefb755e54cac7b5e61fa7778ae107102ae 100644
--- a/installer/resources/themes/snark/vanilla/snark.css
+++ b/installer/resources/themes/snark/vanilla/snark.css
@@ -166,7 +166,7 @@ tr {
 }
 
 thead, tfoot {
-     background: url("images/bling2.png") repeat-x scroll center center #867;
+     background: url('images/bling2.png') repeat-x scroll center center #867;
      font-weight: bold;
      color: #503;
 }
diff --git a/router/java/src/net/i2p/router/StatisticsManager.java b/router/java/src/net/i2p/router/StatisticsManager.java
index 9379df3504472df9a640d5837218394b46a34bde..eeda3709c80dbd45d72bf5f4f671f9cdaaa1327e 100644
--- a/router/java/src/net/i2p/router/StatisticsManager.java
+++ b/router/java/src/net/i2p/router/StatisticsManager.java
@@ -71,9 +71,8 @@ public class StatisticsManager {
     public Properties publishStatistics(Hash h) { 
         Properties stats = new Properties();
         stats.setProperty("router.version", RouterVersion.VERSION);
-        // scheduled for removal, never used
-        if (CoreVersion.VERSION.equals("0.9.23"))
-            stats.setProperty("coreVersion", CoreVersion.VERSION);
+        // never used
+        //stats.setProperty("coreVersion", CoreVersion.VERSION);
         stats.setProperty(RouterInfo.PROP_NETWORK_ID, _networkID);
         stats.setProperty(RouterInfo.PROP_CAPABILITIES, _context.router().getCapabilities());
 
@@ -168,9 +167,7 @@ public class StatisticsManager {
         }
 
         // So that we will still get build requests - not required since 0.7.9 2010-01-12
-        // scheduled for removal
-        if (CoreVersion.VERSION.equals("0.9.23"))
-            stats.setProperty("stat_uptime", "90m");
+        //stats.setProperty("stat_uptime", "90m");
         if (FloodfillNetworkDatabaseFacade.isFloodfill(_context.router().getRouterInfo())) {
             int ri = _context.router().getUptime() > 30*60*1000 ?
                      _context.netDb().getKnownRouters() :
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlySearchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlySearchJob.java
index 39e410185412f917eb0f56fd1d48ae490e135d3b..6a8e6da1787b9627b4129b2117b02bca12ba7986 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlySearchJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodOnlySearchJob.java
@@ -232,6 +232,7 @@ class FloodOnlySearchJob extends FloodSearchJob {
         synchronized (this) {
             if (_dead) return;
             _dead = true;
+            super.success();
         }
         if (_log.shouldLog(Log.INFO))
             _log.info(getJobId() + ": Floodfill search for " + _key + " successful");
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/FloodSearchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/FloodSearchJob.java
index 316cf3ff6ba0006a2fbcbe1c71a0e795f2e92c5a..99e212e977366375c895e0ce6f524cbb456bba21 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/FloodSearchJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/FloodSearchJob.java
@@ -33,6 +33,7 @@ public class FloodSearchJob extends JobImpl {
     protected final AtomicInteger _lookupsRemaining = new AtomicInteger();
     protected volatile boolean _dead;
     protected final long _created;
+    protected boolean _success;
 
     /**
      *  @param onFind may be null
@@ -69,6 +70,7 @@ public class FloodSearchJob extends JobImpl {
      *  @param isLease ignored
      */
     void addDeferred(Job onFind, Job onFailed, long timeoutMs, boolean isLease) {
+        boolean success;
         synchronized (this) {
             if (!_dead) {
                 if (onFind != null)
@@ -77,9 +79,13 @@ public class FloodSearchJob extends JobImpl {
                     _onFailed.add(onFailed);
                 return;
             }
+            success = _success;
         }
         // outside synch to avoid deadlock with job queue
-        getContext().jobQueue().addJob(onFailed);
+        if (success && onFind != null)
+            getContext().jobQueue().addJob(onFind);
+        else if (!success && onFailed != null)
+            getContext().jobQueue().addJob(onFailed);
     }
 
     /** using context clock */
@@ -193,8 +199,11 @@ public class FloodSearchJob extends JobImpl {
      *  Deprecated, unused, see FOSJ override
      */
     void success() {
-        throw new UnsupportedOperationException("use override");
+        synchronized(this) {
+            _success = true;
+        }
 /****
+        throw new UnsupportedOperationException("use override");
         if (_dead) return;
         if (_log.shouldLog(Log.INFO))
             _log.info(getJobId() + ": Floodfill search for " + _key.toBase64() + " successful");
diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java b/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java
index 58f045c284d52dd4c0a721e9ccaa221706324947..014924bab326704b29974030de63979aafd586d0 100644
--- a/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java
+++ b/router/java/src/net/i2p/router/networkdb/kademlia/IterativeSearchJob.java
@@ -587,6 +587,7 @@ class IterativeSearchJob extends FloodSearchJob {
         synchronized(this) {
             if (_dead) return;
             _dead = true;
+            _success = true;
             tries = _unheardFrom.size() + _failedPeers.size();
             if (_unheardFrom.size() == 1) {
                 peer = _unheardFrom.iterator().next();