diff --git a/apps/desktopgui/src/router/configuration/PeerHelper.java b/apps/desktopgui/src/router/configuration/PeerHelper.java
index 54d71cbc2f621f7662bf943a691a19ed6285c9b9..76ffeef8777077fcf1b131d8943da125d29521f6 100644
--- a/apps/desktopgui/src/router/configuration/PeerHelper.java
+++ b/apps/desktopgui/src/router/configuration/PeerHelper.java
@@ -49,7 +49,7 @@ public class PeerHelper {
                 return "ERROR: The UDP port is already in use. Set i2np.udp.internalPort=xxxx to a different value in the advanced config and restart";
             case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
             default:
-                ra = context.router().getRouterInfo().getTargetAddress("UDP");
+                ra = context.router().getRouterInfo().getTargetAddress("SSU");
                 if (ra == null && context.router().getUptime() > 5*60*1000) {
                     if (context.getProperty(PROP_I2NP_NTCP_HOSTNAME) == null ||
                         context.getProperty(PROP_I2NP_NTCP_PORT) == null)
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java
index 12931f3a27a9d02a582c2358465263f586c9c87f..36edc0766029b7b37e167c9eca335def90506ceb 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClient.java
@@ -39,7 +39,7 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
             return;
         }
 
-        StringTokenizer tok = new StringTokenizer(destinations, ",");
+        StringTokenizer tok = new StringTokenizer(destinations, ", ");
         dests = new ArrayList(1);
         while (tok.hasMoreTokens()) {
             String destination = tok.nextToken();
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java
index c4eafde506f53114ed79182c06d9789fe78b2652..3c571857afc506de94539133b3387243553ff729 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelClientBase.java
@@ -345,7 +345,9 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
     public I2PSocket createI2PSocket(Destination dest) throws I2PException, ConnectException, NoRouteToHostException, InterruptedIOException {
         if (sockMgr == null) {
             // we need this before getDefaultOptions()
-            sockMgr = getSocketManager();
+            synchronized(sockLock) {
+                sockMgr = getSocketManager();
+            }
         }
         return createI2PSocket(dest, getDefaultOptions());
     }
@@ -369,9 +371,12 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
 
         if (sockMgr == null) {
             // delayed open - call get instead of build because the locking is up there
-            sockMgr = getSocketManager();
-        } else if (Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.newDestOnResume")).booleanValue()) {
-            synchronized(sockMgr) {
+            synchronized(sockLock) {
+                sockMgr = getSocketManager();
+            }
+        } else if (Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.closeOnIdle")).booleanValue() &&
+                   Boolean.valueOf(getTunnel().getClientOptions().getProperty("i2cp.newDestOnResume")).booleanValue()) {
+            synchronized(sockLock) {
                 I2PSocketManager oldSockMgr = sockMgr;
                 // This will build a new socket manager and a new dest if the session is closed.
                 sockMgr = getSocketManager();
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
index 53c3136b20f86a6d5c5a6053ffe2350859ff7f6b..316731deec7f44c57ba141d7a19c718effd467a9 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
@@ -211,8 +211,11 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
         if (!defaultOpts.contains("i2p.streaming.inactivityTimeout"))
             defaultOpts.setProperty("i2p.streaming.inactivityTimeout", ""+DEFAULT_READ_TIMEOUT);
         // delayed start
-        if (sockMgr == null)
-            sockMgr = getSocketManager();
+        if (sockMgr == null) {
+            synchronized(sockLock) {
+                sockMgr = getSocketManager();
+            }
+        }
         I2PSocketOptions opts = sockMgr.buildOptions(defaultOpts);
         if (!defaultOpts.containsKey(I2PSocketOptions.PROP_CONNECT_TIMEOUT))
             opts.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT);
diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java
index a029de725a874dcadc3ab543ef23065807c1fdf5..d606467c529629ab304d8d205372d4c6d9ac8d87 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/web/EditBean.java
@@ -153,7 +153,9 @@ public class EditBean extends IndexBean {
     }
     
     public boolean getNewDest(int tunnel) {
-        return getBooleanProperty(tunnel, "i2cp.newDestOnResume");
+        return getBooleanProperty(tunnel, "i2cp.newDestOnResume") &&
+               getBooleanProperty(tunnel, "i2cp.closeOnIdle") &&
+               !getBooleanProperty(tunnel, "persistentClientKey");
     }
     
     public boolean getPersistentClientKey(int tunnel) {
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 8663d35fe3048f28f4fd5f29208134be3f48288f..f85d8dc93865a8b2e901ce25b7e1c9c30976ffd6 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/SummaryHelper.java
@@ -135,7 +135,7 @@ public class SummaryHelper extends HelperBase {
                 return "ERR-UDP Port In Use - Set i2np.udp.internalPort=xxxx in advanced config and restart";
             case CommSystemFacade.STATUS_UNKNOWN: // fallthrough
             default:
-                ra = _context.router().getRouterInfo().getTargetAddress("UDP");
+                ra = _context.router().getRouterInfo().getTargetAddress("SSU");
                 if (ra == null && _context.router().getUptime() > 5*60*1000) {
                     if (_context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_HOSTNAME) == null ||
                         _context.getProperty(ConfigNetHelper.PROP_I2NP_NTCP_PORT) == null)
diff --git a/apps/routerconsole/jsp/logs.jsp b/apps/routerconsole/jsp/logs.jsp
index a102912488fe59f56ab86d674260eecc053d662d..dbaca04033fa20842cd7f422c00f0cb7daa3ebbf 100644
--- a/apps/routerconsole/jsp/logs.jsp
+++ b/apps/routerconsole/jsp/logs.jsp
@@ -17,6 +17,8 @@
 I2P <jsp:getProperty name="helper" property="version" /><br />
 <%=System.getProperty("java.vendor")%> <%=System.getProperty("java.version")%><br />
 <%=System.getProperty("os.name")%> <%=System.getProperty("os.arch")%> <%=System.getProperty("os.version")%><br />
+CPU <%=net.i2p.util.NativeBigInteger.cpuModel()%> (<%=net.i2p.util.NativeBigInteger.cpuType()%>)<br />
+jbigi <%=net.i2p.util.NativeBigInteger.loadStatus()%><br />
  </p>
  <hr />
  <jsp:useBean class="net.i2p.router.web.LogsHelper" id="logsHelper" scope="request" />
diff --git a/apps/susidns/src/build.xml b/apps/susidns/src/build.xml
index be34b4879e3fa706f1325a0e2d4d670b89b109bf..6f82b26b19b11c321096b3e7fce8b85070ba09ec 100644
--- a/apps/susidns/src/build.xml
+++ b/apps/susidns/src/build.xml
@@ -37,7 +37,7 @@
         <echo message="Ignore any warning about /WEB-INF/web.xml not found" />
         <java classname="org.apache.jasper.JspC" fork="true" classpathref="cp">
             <arg value="-d" />
-            <arg value="WEB-INF/classes" />
+            <arg value="${tmp}" />
             <arg value="-v" />
             <arg value="-p" />
             <arg value="i2p.susi.dns.jsp" />
@@ -47,7 +47,7 @@
             <arg value="./jsp" />
         </java>
         <javac debug="true" deprecation="on" source="1.5" target="1.5" 
-               destdir="${bin}" srcdir="./WEB-INF/classes" includes="**/*.java" classpathref="cp">
+               destdir="${bin}" srcdir="${tmp}" includes="**/*.java" classpathref="cp">
 		<compilerarg line="${javac.compilerargs}" />
          </javac>
         <copy file="WEB-INF/web-template.xml" tofile="WEB-INF/web-out.xml" />
@@ -85,6 +85,7 @@
         <fileset dir="WEB-INF" includes="web-fragment.xml, web-out.xml" />
       </delete>
       <delete dir="${bin}" />
+      <delete dir="${tmp}" />
     </target>
     <target name="distclean" depends="clean" />
 </project>
diff --git a/build.xml b/build.xml
index 453b0d44c3c415927179845757d4a3269f2e131d..6ed84ca7342ec9807598e7c8c1773c6f3e102044 100644
--- a/build.xml
+++ b/build.xml
@@ -323,6 +323,14 @@
             <tarfileset dir="pkg-temp" includes="**/*" prefix="i2p" />
         </tar>
     </target>
+    <target name="consoleDocs">
+        <delete dir="pkg-temp" />
+        <copy todir="pkg-temp/docs/" >
+          <fileset dir="." includes="readme*.html" />
+          <fileset dir="installer/resources/" includes="*-header.ht" />
+        </copy>
+        <zip destfile="docs.zip" basedir="pkg-temp" />
+    </target>
     <target name="updater" depends="prepupdate">
         <zip destfile="i2pupdate.zip" basedir="pkg-temp" />
     </target>
@@ -373,8 +381,10 @@
         <copy file="build/routerconsole.war" todir="pkg-temp/webapps/" />
         <copy file="build/addressbook.war" todir="pkg-temp/webapps/" />
         <!-- New readme_*.html files - For one release only -->
+        <!--
         <mkdir dir="pkg-temp/docs" />
         <copy file="readme_fr.html" todir="pkg-temp/docs/" />
+        -->
     </target>
     <target name="prepupdateRouter" depends="buildrouter">
         <delete dir="pkg-temp" />
diff --git a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java
index 0d71677a970a2f199a9a262dfe915528914ad9c4..80cd18ac8b5aa4318c7590ba21033fdf3b3830f3 100644
--- a/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java
+++ b/core/java/src/net/i2p/crypto/TransientSessionKeyManager.java
@@ -325,6 +325,7 @@ class TransientSessionKeyManager extends SessionKeyManager {
         int recent = 0;
         int tags = 0;
         int toRemove = overage * 2;
+        _log.log(Log.CRIT, "TOO MANY SESSION TAGS! Starting cleanup, overage = " + overage);
         List removed = new ArrayList(toRemove);
         synchronized (_inboundTagSets) {
             for (Iterator iter = _inboundTagSets.values().iterator(); iter.hasNext(); ) {
diff --git a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java
index 79066c4c62345044a87c71d3eb9b5d147b66bf54..5c79d94f3c70ca356c0e2a8918451299953fe761 100644
--- a/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java
+++ b/core/java/src/net/i2p/data/i2cp/I2CPMessageReader.java
@@ -143,7 +143,6 @@ public class I2CPMessageReader {
                     _log.error("Error closing the stream", ioe);
                 }
             }
-            _stream = null;
         }
 
         public void run() {
@@ -186,7 +185,7 @@ public class I2CPMessageReader {
                     }
                 }
             }
-            // boom bye bye bad bwoy
+            _stream = null;
         }
     }
 }
diff --git a/core/java/src/net/i2p/util/NativeBigInteger.java b/core/java/src/net/i2p/util/NativeBigInteger.java
index 970de52c85d61dfd3cd40fc8dcce04ed55705d4a..a6d7e97925e9e4e3151f8a671a393b64821453c5 100644
--- a/core/java/src/net/i2p/util/NativeBigInteger.java
+++ b/core/java/src/net/i2p/util/NativeBigInteger.java
@@ -88,6 +88,8 @@ import net.i2p.util.Log;
 public class NativeBigInteger extends BigInteger {
     /** did we load the native lib correctly? */
     private static boolean _nativeOk = false;
+    private static String _loadStatus = "uninitialized";
+    private static String _cpuModel = "uninitialized";
     /** 
      * do we want to dump some basic success/failure info to stderr during 
      * initialization?  this would otherwise use the Log component, but this makes
@@ -140,6 +142,9 @@ public class NativeBigInteger extends BigInteger {
         
         try {
             CPUInfo c = CPUID.getInfo();
+            try {
+                _cpuModel = c.getCPUModelString();
+            } catch (UnknownCPUException e) {}
             if (c.IsC3Compatible())
                 return JBIGI_OPTIMIZATION_VIAC3;
             if (c instanceof AMDCPUInfo) {
@@ -256,6 +261,20 @@ public class NativeBigInteger extends BigInteger {
         return _nativeOk;
     }
  
+    public static String loadStatus() {
+        return _loadStatus;
+    }
+ 
+    public static String cpuType() {
+        if (sCPUType != null)
+            return sCPUType;
+        return "unrecognized";
+    }
+ 
+    public static String cpuModel() {
+        return _cpuModel;
+    }
+ 
     /**
      * <p>Compare the BigInteger.modPow/doubleValue vs the NativeBigInteger.modPow/doubleValue of some 
      * really big (2Kbit) numbers 100 different times and benchmark the 
@@ -455,12 +474,14 @@ public class NativeBigInteger extends BigInteger {
         if(_doLog)
             System.err.println("INFO: " + s);
         I2PAppContext.getGlobalContext().logManager().getLog(NativeBigInteger.class).info(s);
+        _loadStatus = s;
     }
 
     private static void warn(String s) {
         if(_doLog)
             System.err.println("WARNING: " + s);
         I2PAppContext.getGlobalContext().logManager().getLog(NativeBigInteger.class).warn(s);
+        _loadStatus = s;
     }
 
     /** 
diff --git a/core/java/src/net/i2p/util/ShellCommand.java b/core/java/src/net/i2p/util/ShellCommand.java
index 36f0dfd210af1d4a6b6df26d016ec71a5b3d973c..80bdc32f65b31b412c3bf5fca62e0899dbe1b758 100644
--- a/core/java/src/net/i2p/util/ShellCommand.java
+++ b/core/java/src/net/i2p/util/ShellCommand.java
@@ -34,6 +34,7 @@ public class ShellCommand {
     private static final boolean NO_WAIT_FOR_EXIT_STATUS = false;
 
     private boolean       _commandSuccessful;
+    private boolean       _commandCompleted;
     private CommandThread _commandThread;
     private InputStream   _errorStream;
     private InputStream   _inputStream;
@@ -43,6 +44,8 @@ public class ShellCommand {
 
     /**
      * Executes a shell command in its own thread.
+     * Use caution when repeatedly calling execute methods with the same object
+     * as there are some globals here...
      * 
      * @author hypercubus
      */
@@ -57,11 +60,16 @@ public class ShellCommand {
             this.caller = caller;
             this.shellCommand = shellCommand;
             this.consumeOutput = consumeOutput;
+            _commandSuccessful = false;
+            _commandCompleted = false;
         }
 
         @Override
         public void run() {
+            // FIXME these will corrupt the globals if the command times out and the caller
+            // makes another request with the same object.
             _commandSuccessful = execute(shellCommand, consumeOutput, WAIT_FOR_EXIT_STATUS);
+            _commandCompleted = true;
             if (_isTimerRunning) {
                 synchronized(caller) {
                     caller.notifyAll();  // In case the caller is still in the wait() state.
@@ -248,7 +256,8 @@ public class ShellCommand {
                 _isTimerRunning = true;
                 wait(seconds * 1000);
                 _isTimerRunning = false;
-                return true;
+                if (!_commandCompleted)
+                    return true;
             }
 
         } catch (InterruptedException e) {
@@ -317,7 +326,8 @@ public class ShellCommand {
                 _isTimerRunning = true;
                 wait(seconds * 1000);
                 _isTimerRunning = false;
-                return true;
+                if (!_commandCompleted)
+                    return true;
             }
 
         } catch (InterruptedException e) {
diff --git a/installer/resources/clients.config b/installer/resources/clients.config
index 9d0c1b583e8fe82db8a7096a32b634926ec083cd..170f4c8fe5f0a6c5098f61a1247521295ec44406 100644
--- a/installer/resources/clients.config
+++ b/installer/resources/clients.config
@@ -28,7 +28,7 @@ clientApp.3.startOnLoad=true
 clientApp.4.main=net.i2p.apps.systray.UrlLauncher
 clientApp.4.name=consoleBrowser
 clientApp.4.args=http://127.0.0.1:7657/index.jsp
-clientApp.4.delay=5
+clientApp.4.delay=15
 clientApp.4.startOnLoad=true
 
 # BOB bridge
diff --git a/router/java/src/net/i2p/router/client/CreateSessionJob.java b/router/java/src/net/i2p/router/client/CreateSessionJob.java
index 11608980de20d64c424cf5fc9c2451edaab978da..0ee1f177f7dc5e9b434c8998d1bec54cb212f4a9 100644
--- a/router/java/src/net/i2p/router/client/CreateSessionJob.java
+++ b/router/java/src/net/i2p/router/client/CreateSessionJob.java
@@ -59,10 +59,10 @@ class CreateSessionJob extends JobImpl {
         // XXX props.putAll(Router.getInstance().getConfigMap());
         
         // override them by the client's settings
-        props.putAll(_runner.getConfig().getOptions());
+        props.putAll(cfg.getOptions());
         
         // and load 'em up (using anything not yet set as the software defaults)
         settings.readFromProperties(props);
-        getContext().tunnelManager().buildTunnels(_runner.getConfig().getDestination(), settings);
+        getContext().tunnelManager().buildTunnels(cfg.getDestination(), settings);
     }
 }