diff --git a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
index 13f19d0c7a19b6e082e242499b5e89e97757645e..445d92680baf1df63d82fd79f58dab308aa78b58 100644
--- a/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
+++ b/apps/i2ptunnel/java/src/net/i2p/i2ptunnel/I2PTunnelHTTPClient.java
@@ -82,6 +82,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
          "the following Destination:<BR><BR>")
         .getBytes();
 
+    private final static byte[] ERR_NO_OUTPROXY =
+        ("HTTP/1.1 503 Service Unavailable\r\n"+
+         "Content-Type: text/html; charset=iso-8859-1\r\n"+
+         "Cache-control: no-cache\r\n"+
+         "\r\n"+
+         "<html><body><H1>I2P ERROR: No outproxy found</H1>"+
+         "Your request was for a site outside of I2P, but you have no "+
+         "HTTP outproxy configured.  Please configure an outproxy in I2PTunnel")
+         .getBytes();
+    
     /** used to assign unique IDs to the threads / clients.  no logic or functionality */
     private static volatile long __clientId = 0;
 
@@ -113,23 +123,33 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
         notifyEvent("openHTTPClientResult", "ok");
     }
 
-    private String getPrefix() { return "Client[" + _clientId + "]: "; }
+    private String getPrefix(long requestId) { return "Client[" + _clientId + "/" + requestId + "]: "; }
     
     private String selectProxy() {
-        if (proxyList.size() <= 0) {
-            l.log("Proxy list is emtpy - no outproxy available");
-            return null;
+        synchronized (proxyList) {
+            int size = proxyList.size();
+            if (size <= 0) {
+                if (_log.shouldLog(Log.INFO))
+                    _log.info("Proxy list is empty - no outproxy available");
+                l.log("Proxy list is emtpy - no outproxy available");
+                return null;
+            }
+            int index = I2PAppContext.getGlobalContext().random().nextInt(size);
+            if (index >= size) index = size - 1;
+            if (index < 0) return null;
+            String proxy = (String)proxyList.get(index);
+            return proxy;
         }
-        int index = I2PAppContext.getGlobalContext().random().nextInt(proxyList.size());
-        return (String)proxyList.get(index);
     }
     
+    private static long __requestId = 0;
     protected void clientConnectionRun(Socket s) {
         OutputStream out = null;
         String targetRequest = null;
         boolean usingWWWProxy = false;
         String currentProxy = null;
         InactivityTimeoutThread timeoutThread = null;
+        long requestId = ++__requestId;
         try {
             out = s.getOutputStream();
             BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(), "ISO-8859-1"));
@@ -137,7 +157,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
             StringBuffer newRequest = new StringBuffer();
             while ((line = br.readLine()) != null) {
                 if (_log.shouldLog(Log.DEBUG))
-                    _log.debug(getPrefix() + "Line=[" + line + "]");
+                    _log.debug(getPrefix(requestId) + "Line=[" + line + "]");
                 
                 if (line.startsWith("Connection: ") || 
                     line.startsWith("Keep-Alive: ") || 
@@ -146,7 +166,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
                 
                 if (method == null) { // first line (GET /base64/realaddr)
                     if (_log.shouldLog(Log.DEBUG))
-                        _log.debug(getPrefix() + "Method is null for [" + line + "]");
+                        _log.debug(getPrefix(requestId) + "Method is null for [" + line + "]");
                     
                     int pos = line.indexOf(" ");
                     if (pos == -1) break;
@@ -179,11 +199,29 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
                         line = method + " " + request.substring(pos);
                     } else if (host.indexOf(".") != -1) {
                         // The request must be forwarded to a WWW proxy
+                        if (_log.shouldLog(Log.DEBUG))
+                            _log.debug("Before selecting outproxy for " + host);
                         currentProxy = selectProxy();
+                        if (_log.shouldLog(Log.DEBUG))
+                            _log.debug("After selecting outproxy for " + host + ": " + currentProxy);
+                        if (currentProxy == null) {
+                            if (_log.shouldLog(Log.WARN))
+                                _log.warn(getPrefix(requestId) + "Host wants to be outproxied, but we dont have any!");
+                            l.log("No HTTP outproxy found for the request.");
+                            if (out != null) {
+                                out.write(ERR_NO_OUTPROXY);
+                                out.write("<p /><i>Generated on: ".getBytes());
+                                out.write(new Date().toString().getBytes());
+                                out.write("</i></body></html>\n".getBytes());
+                                out.flush();
+                            }
+                            s.close();
+                            return;
+                        }
                         destination = currentProxy;
                         usingWWWProxy = true;
                         if (_log.shouldLog(Log.DEBUG))
-                            _log.debug(getPrefix() + "Host doesnt end with .i2p and it contains a period [" + host + "]: wwwProxy!");
+                            _log.debug(getPrefix(requestId) + "Host doesnt end with .i2p and it contains a period [" + host + "]: wwwProxy!");
                     } else {
                         request = request.substring(pos + 1);
                         pos = request.indexOf("/");
@@ -193,27 +231,27 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
 
                     boolean isValid = usingWWWProxy || isSupportedAddress(host, protocol);
                     if (!isValid) {
-                        if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "notValid(" + host + ")");
+                        if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "notValid(" + host + ")");
                         method = null;
                         destination = null;
                         break;
                     } else if (!usingWWWProxy) {
-                        if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "host=getHostName(" + destination + ")");
+                        if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(requestId) + "host=getHostName(" + destination + ")");
                         host = getHostName(destination); // hide original host
                     }
 
                     if (_log.shouldLog(Log.DEBUG)) {
-                        _log.debug(getPrefix() + "METHOD:" + method + ":");
-                        _log.debug(getPrefix() + "PROTOC:" + protocol + ":");
-                        _log.debug(getPrefix() + "HOST  :" + host + ":");
-                        _log.debug(getPrefix() + "DEST  :" + destination + ":");
+                        _log.debug(getPrefix(requestId) + "METHOD:" + method + ":");
+                        _log.debug(getPrefix(requestId) + "PROTOC:" + protocol + ":");
+                        _log.debug(getPrefix(requestId) + "HOST  :" + host + ":");
+                        _log.debug(getPrefix(requestId) + "DEST  :" + destination + ":");
                     }
                     
                 } else {
                     if (line.startsWith("Host: ") && !usingWWWProxy) {
                         line = "Host: " + host;
                         if (_log.shouldLog(Log.INFO)) 
-                            _log.info(getPrefix() + "Setting host = " + host);
+                            _log.info(getPrefix(requestId) + "Setting host = " + host);
                     }
                 }
                 
@@ -225,7 +263,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
                 }
             }
             if (_log.shouldLog(Log.DEBUG))
-                _log.debug(getPrefix() + "NewRequest header: [" + newRequest.toString() + "]");
+                _log.debug(getPrefix(requestId) + "NewRequest header: [" + newRequest.toString() + "]");
             
             while (br.ready()) { // empty the buffer (POST requests)
                 int i = br.read();
@@ -247,7 +285,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
             }
             
             if (_log.shouldLog(Log.DEBUG))
-                _log.debug(getPrefix() + "Destination: " + destination);
+                _log.debug(getPrefix(requestId) + "Destination: " + destination);
             
             Destination dest = I2PTunnel.destFromName(destination);
             if (dest == null) {
@@ -262,25 +300,25 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
             I2PSocket i2ps = createI2PSocket(dest);
             byte[] data = newRequest.toString().getBytes("ISO-8859-1");
             I2PTunnelRunner runner = new I2PTunnelRunner(s, i2ps, sockLock, data);
-            timeoutThread = new InactivityTimeoutThread(runner, out, targetRequest, usingWWWProxy, currentProxy, s);
+            timeoutThread = new InactivityTimeoutThread(runner, out, targetRequest, usingWWWProxy, currentProxy, s, requestId);
             timeoutThread.start();
         } catch (SocketException ex) {
             if (timeoutThread != null) timeoutThread.disable();
-            _log.info(getPrefix() + "Error trying to connect", ex);
+            _log.info(getPrefix(requestId) + "Error trying to connect", ex);
             l.log(ex.getMessage());
-            handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy);
+            handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
             closeSocket(s);
         } catch (IOException ex) {
             if (timeoutThread != null) timeoutThread.disable();
-            _log.info(getPrefix() + "Error trying to connect", ex);
+            _log.info(getPrefix(requestId) + "Error trying to connect", ex);
             l.log(ex.getMessage());
-            handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy);
+            handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
             closeSocket(s);
         } catch (I2PException ex) {
             if (timeoutThread != null) timeoutThread.disable();
-            _log.info("getPrefix() + Error trying to connect", ex);
+            _log.info("getPrefix(requestId) + Error trying to connect", ex);
             l.log(ex.getMessage());
-            handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy);
+            handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, currentProxy, requestId);
             closeSocket(s);
         }
     }
@@ -289,18 +327,19 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
     private static volatile long __timeoutId = 0;
 
     private class InactivityTimeoutThread extends I2PThread {
-
+        
         private Socket s;
         private I2PTunnelRunner _runner;
         private OutputStream _out;
         private String _targetRequest;
         private boolean _useWWWProxy;
         private String _currentProxy;
+        private long _requestId;
         private boolean _disabled;
         private Object _disableLock = new Object();
 
         public InactivityTimeoutThread(I2PTunnelRunner runner, OutputStream out, String targetRequest,
-                                       boolean useWWWProxy, String currentProxy, Socket s) {
+                                       boolean useWWWProxy, String currentProxy, Socket s, long requestId) {
             this.s = s;
             _runner = runner;
             _out = out;
@@ -308,8 +347,9 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
             _useWWWProxy = useWWWProxy;
             _currentProxy = currentProxy;
             _disabled = false;
+            _requestId = requestId;
             long timeoutId = ++__timeoutId;
-            setName("InactivityThread " + getPrefix() + timeoutId);
+            setName("InactivityThread " + getPrefix(requestId) + timeoutId);
         }
 
         public void disable() {
@@ -322,13 +362,13 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
         public void run() {
             while (!_disabled) {
                 if (_runner.isFinished()) {
-                    if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "HTTP client request completed prior to timeout");
+                    if (_log.shouldLog(Log.INFO)) _log.info(getPrefix(_requestId) + "HTTP client request completed prior to timeout");
                     return;
                 }
                 if (_runner.getLastActivityOn() < Clock.getInstance().now() - INACTIVITY_TIMEOUT) {
                     if (_runner.getStartedOn() < Clock.getInstance().now() - INACTIVITY_TIMEOUT) {
                         if (_log.shouldLog(Log.WARN))
-                            _log.warn(getPrefix() + "HTTP client request timed out (lastActivity: "
+                            _log.warn(getPrefix(_requestId) + "HTTP client request timed out (lastActivity: "
                                       + new Date(_runner.getLastActivityOn()) + ", startedOn: "
                                       + new Date(_runner.getStartedOn()) + ")");
                         timeout();
@@ -349,7 +389,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
         }
 
         private void timeout() {
-            _log.info(getPrefix() + "Inactivity timeout reached");
+            _log.info(getPrefix(_requestId) + "Inactivity timeout reached");
             l.log("Inactivity timeout reached");
             if (_out != null) {
                 try {
@@ -359,16 +399,17 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
                         writeErrorMessage(ERR_TIMEOUT, _out, _targetRequest, _useWWWProxy, _currentProxy);
                     }
                 } catch (IOException ioe) {
-                    _log.warn(getPrefix() + "Error writing out the 'timeout' message", ioe);
+                    _log.warn(getPrefix(_requestId) + "Error writing out the 'timeout' message", ioe);
                 }
             } else {
-                _log.warn(getPrefix() + "Client disconnected before we could say we timed out");
+                _log.warn(getPrefix(_requestId) + "Client disconnected before we could say we timed out");
             }
             closeSocket(s);
         }
     }
 
     private final static String getHostName(String host) {
+        if (host == null) return null;
         try {
             Destination dest = I2PTunnel.destFromName(host);
             if (dest == null) return "i2p";
@@ -394,18 +435,18 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
     }
 
     private void handleHTTPClientException(Exception ex, OutputStream out, String targetRequest,
-                                                  boolean usingWWWProxy, String wwwProxy) {
+                                                  boolean usingWWWProxy, String wwwProxy, long requestId) {
                                                       
         if (_log.shouldLog(Log.WARN))
-            _log.warn("Error sending to " + wwwProxy + " (proxy? " + usingWWWProxy + ", request: " + targetRequest, ex);
+            _log.warn(getPrefix(requestId) + "Error sending to " + wwwProxy + " (proxy? " + usingWWWProxy + ", request: " + targetRequest, ex);
         if (out != null) {
             try {
                 writeErrorMessage(ERR_DESTINATION_UNKNOWN, out, targetRequest, usingWWWProxy, wwwProxy);
             } catch (IOException ioe) {
-                _log.warn(getPrefix() + "Error writing out the 'destination was unknown' " + "message", ioe);
+                _log.warn(getPrefix(requestId) + "Error writing out the 'destination was unknown' " + "message", ioe);
             }
         } else {
-            _log.warn(getPrefix() + "Client disconnected before we could say that destination " + "was unknown", ex);
+            _log.warn(getPrefix(requestId) + "Client disconnected before we could say that destination " + "was unknown", ex);
         }
     }