diff --git a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java
index 34eaee9efab37ed4355633f3b94ea9f56e6afb26..6303b385c4efde96761776569dea8eb7fad55fae 100644
--- a/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java
+++ b/router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java
@@ -392,6 +392,7 @@ class BuildExecutor implements Runnable {
                 pools.clear();
             } catch (RuntimeException e) {
                     _log.log(Log.CRIT, "B0rked in the tunnel builder", e);
+                    try { Thread.sleep(LOOP_TIME); } catch (InterruptedException ie) {}
             }
         }
         
diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java
index 1668ecb05bc8abe7e546fc562b25375ded01bebd..8304a1c7098d7d8ae69187c6876e9e2a31926413 100644
--- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java
+++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPool.java
@@ -75,7 +75,7 @@ public class TunnelPool {
      *  Destination (i.e. for servers or clients w/ persistent key,
      *  or restarting close-on-idle clients)
      */
-    void startup() {
+    synchronized void startup() {
         synchronized (_inProgress) {
             _inProgress.clear();
         }
@@ -102,7 +102,7 @@ public class TunnelPool {
                                new long[] { 5*60*1000l });
     }
     
-    void shutdown() {
+    synchronized void shutdown() {
         if (_log.shouldLog(Log.WARN))
             _log.warn(toString() + ": Shutdown called");
         _alive = false;
diff --git a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java
index bda1fe727fd3a075aa36580136492185d85adffd..42f7b189bd4ed9861de1b2ff2971adc9b6dfd11c 100644
--- a/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java
+++ b/router/java/src/net/i2p/router/tunnel/pool/TunnelPoolManager.java
@@ -37,8 +37,8 @@ public class TunnelPoolManager implements TunnelManagerFacade {
     private final Map<Hash, TunnelPool> _clientInboundPools;
     /** Hash (destination) to TunnelPool */
     private final Map<Hash, TunnelPool> _clientOutboundPools;
-    private TunnelPool _inboundExploratory;
-    private TunnelPool _outboundExploratory;
+    private final TunnelPool _inboundExploratory;
+    private final TunnelPool _outboundExploratory;
     private final BuildExecutor _executor;
     private final BuildHandler _handler;
     private final TunnelPeerSelector _clientPeerSelector;
@@ -62,10 +62,19 @@ public class TunnelPoolManager implements TunnelManagerFacade {
         _clientInboundPools = new ConcurrentHashMap(4);
         _clientOutboundPools = new ConcurrentHashMap(4);
         _clientPeerSelector = new ClientPeerSelector(ctx);
+
+        ExploratoryPeerSelector selector = new ExploratoryPeerSelector(_context);
+        TunnelPoolSettings inboundSettings = new TunnelPoolSettings();
+        inboundSettings.setIsExploratory(true);
+        inboundSettings.setIsInbound(true);
+        _inboundExploratory = new TunnelPool(_context, this, inboundSettings, selector);
+        TunnelPoolSettings outboundSettings = new TunnelPoolSettings();
+        outboundSettings.setIsExploratory(true);
+        outboundSettings.setIsInbound(false);
+        _outboundExploratory = new TunnelPool(_context, this, outboundSettings, selector);
         
+        // threads will be started in startup()
         _executor = new BuildExecutor(ctx, this);
-        I2PThread execThread = new I2PThread(_executor, "BuildExecutor", true);
-        execThread.start();
         _handler = new BuildHandler(ctx, this, _executor);
         int numHandlerThreads;
         int share = TunnelDispatcher.getShareBandwidth(ctx);
@@ -76,10 +85,6 @@ public class TunnelPoolManager implements TunnelManagerFacade {
         else
             numHandlerThreads = 1;
         _numHandlerThreads = ctx.getProperty("router.buildHandlerThreads", numHandlerThreads);
-        for (int i = 1; i <= _numHandlerThreads; i++) {
-            I2PThread hThread = new I2PThread(_handler, "BuildHandler " + i + '/' + numHandlerThreads, true);
-            hThread.start();
-        }
         
         // The following are for TestJob
         ctx.statManager().createRequiredRateStat("tunnel.testFailedTime", "Time for tunnel test failure (ms)", "Tunnels", 
@@ -104,9 +109,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
      * @return null if none
      */
     public TunnelInfo selectInboundTunnel() { 
-        TunnelPool pool = _inboundExploratory;
-        if (pool == null) return null;
-        TunnelInfo info = pool.selectTunnel(); 
+        TunnelInfo info = _inboundExploratory.selectTunnel(); 
         if (info == null) {
             _inboundExploratory.buildFallback();
             // still can be null, but probably not
@@ -139,13 +142,11 @@ public class TunnelPoolManager implements TunnelManagerFacade {
      * @return null if none
      */
     public TunnelInfo selectOutboundTunnel() { 
-        TunnelPool pool = _outboundExploratory;
-        if (pool == null) return null;
-        TunnelInfo info = pool.selectTunnel();
+        TunnelInfo info = _outboundExploratory.selectTunnel();
         if (info == null) {
-            pool.buildFallback();
+            _outboundExploratory.buildFallback();
             // still can be null, but probably not
-            info = pool.selectTunnel();
+            info = _outboundExploratory.selectTunnel();
         }
         return info;
     }
@@ -176,9 +177,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
      * @since 0.8.10
      */
     public TunnelInfo selectInboundExploratoryTunnel(Hash closestTo) { 
-        TunnelPool pool = _inboundExploratory;
-        if (pool == null) return null;
-        TunnelInfo info = pool.selectTunnel(); 
+        TunnelInfo info = _inboundExploratory.selectTunnel(); 
         if (info == null) {
             _inboundExploratory.buildFallback();
             // still can be null, but probably not
@@ -222,13 +221,11 @@ public class TunnelPoolManager implements TunnelManagerFacade {
      * @since 0.8.10
      */
     public TunnelInfo selectOutboundExploratoryTunnel(Hash closestTo) { 
-        TunnelPool pool = _outboundExploratory;
-        if (pool == null) return null;
-        TunnelInfo info = pool.selectTunnel();
+        TunnelInfo info = _outboundExploratory.selectTunnel();
         if (info == null) {
-            pool.buildFallback();
+            _outboundExploratory.buildFallback();
             // still can be null, but probably not
-            info = pool.selectTunnel(closestTo);
+            info = _outboundExploratory.selectTunnel(closestTo);
         }
         return info;
     }
@@ -261,14 +258,10 @@ public class TunnelPoolManager implements TunnelManagerFacade {
                 if (info != null)
                     return info;
         }
-        if (_inboundExploratory != null) {
-            info = _inboundExploratory.getTunnel(id);
-            if (info != null) return info;
-        }
-        if (_outboundExploratory != null) {
-            info = _outboundExploratory.getTunnel(id);
-            if (info != null) return info;
-        }
+        info = _inboundExploratory.getTunnel(id);
+        if (info != null) return info;
+        info = _outboundExploratory.getTunnel(id);
+        if (info != null) return info;
         return null;
     }
     
@@ -282,9 +275,6 @@ public class TunnelPoolManager implements TunnelManagerFacade {
 
     /** @return number of outbound exploratory tunnels */
     public int getOutboundTunnelCount() { 
-        if (_outboundExploratory == null)
-            return 0;
-        else
             return _outboundExploratory.size(); 
     }
 
@@ -507,22 +497,15 @@ public class TunnelPoolManager implements TunnelManagerFacade {
     public synchronized void startup() { 
         _isShutdown = false;
         if (!_executor.isRunning()) {
-            I2PThread t = new I2PThread(_executor, "BuildExecutor");
-            t.setDaemon(true);
+            I2PThread t = new I2PThread(_executor, "BuildExecutor", true);
             t.start();
+            for (int i = 1; i <= _numHandlerThreads; i++) {
+                I2PThread hThread = new I2PThread(_handler, "BuildHandler " + i + '/' + _numHandlerThreads, true);
+                hThread.start();
+            }
         }
-        ExploratoryPeerSelector selector = new ExploratoryPeerSelector(_context);
         
-        TunnelPoolSettings inboundSettings = new TunnelPoolSettings();
-        inboundSettings.setIsExploratory(true);
-        inboundSettings.setIsInbound(true);
-        _inboundExploratory = new TunnelPool(_context, this, inboundSettings, selector);
         _inboundExploratory.startup();
-        
-        TunnelPoolSettings outboundSettings = new TunnelPoolSettings();
-        outboundSettings.setIsExploratory(true);
-        outboundSettings.setIsInbound(false);
-        _outboundExploratory = new TunnelPool(_context, this, outboundSettings, selector);
         _context.simpleScheduler().addEvent(new DelayedStartup(_outboundExploratory), 3*1000);
         
         // try to build up longer tunnels
@@ -554,9 +537,7 @@ public class TunnelPoolManager implements TunnelManagerFacade {
     }
 
     private void shutdownExploratory() {
-        if (_inboundExploratory != null)
             _inboundExploratory.shutdown();
-        if (_outboundExploratory != null)
             _outboundExploratory.shutdown();
     }
     
@@ -564,10 +545,8 @@ public class TunnelPoolManager implements TunnelManagerFacade {
     public void listPools(List<TunnelPool> out) {
         out.addAll(_clientInboundPools.values());
         out.addAll(_clientOutboundPools.values());
-        if (_inboundExploratory != null)
-            out.add(_inboundExploratory);
-        if (_outboundExploratory != null)
-            out.add(_outboundExploratory);
+        out.add(_inboundExploratory);
+        out.add(_outboundExploratory);
     }
     void tunnelFailed() { _executor.repoll(); }
     BuildExecutor getExecutor() { return _executor; }
@@ -639,12 +618,18 @@ public class TunnelPoolManager implements TunnelManagerFacade {
             return new HashMap(_clientOutboundPools);
     }
 
-    /** for TunnelRenderer in router console */
+    /**
+     *  For TunnelRenderer in router console
+     *  @return non-null
+     */
     public TunnelPool getInboundExploratoryPool() {
         return _inboundExploratory;
     }
 
-    /** for TunnelRenderer in router console */
+    /**
+     *  For TunnelRenderer in router console
+     *  @return non-null
+     */
     public TunnelPool getOutboundExploratoryPool() {
         return _outboundExploratory;
     }
@@ -658,13 +643,11 @@ public class TunnelPoolManager implements TunnelManagerFacade {
      *  @since 0.8.13
      */
     public void fail(Hash peer) {
-        if (_outboundExploratory != null)
-            failTunnelsWithFirstHop(_outboundExploratory, peer);
+        failTunnelsWithFirstHop(_outboundExploratory, peer);
         for (TunnelPool pool : _clientOutboundPools.values()) {
             failTunnelsWithFirstHop(pool, peer);
         }
-        if (_inboundExploratory != null)
-            failTunnelsWithLastHop(_inboundExploratory, peer);
+        failTunnelsWithLastHop(_inboundExploratory, peer);
         for (TunnelPool pool : _clientInboundPools.values()) {
             failTunnelsWithLastHop(pool, peer);
         }