diff --git a/Slackware/i2p-base/rc.i2p_def b/Slackware/i2p-base/rc.i2p_def
index 075e9e8472279bdde4daeef3005fba4f39233d40..c231922e5f59973d16b26fba3321329dc1debcb9 100644
--- a/Slackware/i2p-base/rc.i2p_def
+++ b/Slackware/i2p-base/rc.i2p_def
@@ -4,7 +4,7 @@
 i2p_start() {
  # Check if router is up first!
  /bin/su - -c "( export PATH=\"$PATH:/usr/lib/java/bin:/usr/lib/java/jre/bin\"; directory status )" > /dev/null
- if [ ! $? -eq 0 ] ; then {
+ if [ $? -eq 0 ] ; then {
   # I2p is already running, so tell the user.
   echo "I2P is already running..."
   i2p_status
diff --git a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java
index 8ba5c89696f2581022274f98dd8076225a9f9213..d649b8227cd1c6ab2c53cbcd5161be398a051e66 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/PeerState.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/PeerState.java
@@ -261,11 +261,16 @@ class PeerState implements DataLoader
 
   // This is used to flag that we have to back up from the firstOutstandingRequest
   // when calculating how far we've gotten
-  Request pendingRequest = null;
+  private Request pendingRequest;
 
   /**
-   * Called when a partial piece request has been handled by
+   * Called when a full chunk (i.e. a piece message) has been received by
    * PeerConnectionIn.
+   *
+   * This may block quite a while if it is the last chunk for a piece,
+   * as it calls the listener, who stores the piece and then calls
+   * havePiece for every peer on the torrent (including us).
+   *
    */
   void pieceMessage(Request req)
   {
@@ -273,11 +278,15 @@ class PeerState implements DataLoader
     downloaded += size;
     listener.downloaded(peer, size);
 
-    pendingRequest = null;
+    if (_log.shouldLog(Log.DEBUG))
+      _log.debug("got end of Chunk("
+                  + req.piece + "," + req.off + "," + req.len + ") from "
+                  + peer);
 
     // Last chunk needed for this piece?
     if (getFirstOutstandingRequest(req.piece) == -1)
       {
+        // warning - may block here for a while
         if (listener.gotPiece(peer, req.piece, req.bs))
           {
             if (_log.shouldLog(Log.DEBUG))
@@ -288,9 +297,15 @@ class PeerState implements DataLoader
             if (_log.shouldLog(Log.WARN))
               _log.warn("Got BAD " + req.piece + " from " + peer);
             // XXX ARGH What now !?!
+            // FIXME Why would we set downloaded to 0?
             downloaded = 0;
           }
       }
+
+      // ok done with this one
+      synchronized(this) {
+          pendingRequest = null;
+      }
   }
 
   synchronized private int getFirstOutstandingRequest(int piece)
@@ -303,15 +318,16 @@ class PeerState implements DataLoader
 
   /**
    * Called when a piece message is being processed by the incoming
-   * connection. Returns null when there was no such request. It also
+   * connection. That is, when the header of the piece message was received.
+   * Returns null when there was no such request. It also
    * requeues/sends requests when it thinks that they must have been
    * lost.
    */
   Request getOutstandingRequest(int piece, int begin, int length)
   {
     if (_log.shouldLog(Log.DEBUG))
-      _log.debug("getChunk("
-                  + piece + "," + begin + "," + length + ") "
+      _log.debug("got start of Chunk("
+                  + piece + "," + begin + "," + length + ") from "
                   + peer);
 
     int r = getFirstOutstandingRequest(piece);
@@ -351,6 +367,9 @@ class PeerState implements DataLoader
             downloaded = 0; // XXX - punishment?
             return null;
           }
+
+        // note that this request is being read
+        pendingRequest = req;
         
         // Report missing requests.
         if (r != 0)
@@ -374,13 +393,12 @@ class PeerState implements DataLoader
     // Request more if necessary to keep the pipeline filled.
     addRequest();
 
-    pendingRequest = req;
     return req;
 
   }
 
   // get longest partial piece
-  Request getPartialRequest()
+  synchronized Request getPartialRequest()
   {
     Request req = null;
     for (int i = 0; i < outstandingRequests.size(); i++) {
@@ -401,10 +419,13 @@ class PeerState implements DataLoader
     return req;
   }
 
-  // return array of pieces terminated by -1
-  // remove most duplicates
-  // but still could be some duplicates, not guaranteed
-  int[] getRequestedPieces()
+  /**
+   * return array of pieces terminated by -1
+   * remove most duplicates
+   * but still could be some duplicates, not guaranteed
+   * TODO rework this Java-style to return a Set or a List
+   */
+  synchronized int[] getRequestedPieces()
   {
     int size = outstandingRequests.size();
     int[] arr = new int[size+2];
@@ -514,6 +535,8 @@ class PeerState implements DataLoader
    * @since 0.8.1
    */
   synchronized boolean isRequesting(int piece) {
+      if (pendingRequest != null && pendingRequest.piece == piece)
+          return true;
       for (Request req : outstandingRequests) {
           if (req.piece == piece)
               return true;
@@ -616,6 +639,10 @@ class PeerState implements DataLoader
                 return true;
               }
         }
+
+        // Note that in addition to the bitfield, PeerCoordinator uses
+        // its request tracking and isRequesting() to determine
+        // what piece to give us next.
         int nextPiece = listener.wantPiece(peer, bitfield);
         if (nextPiece != -1
             && (lastRequest == null || lastRequest.piece != nextPiece)) {
diff --git a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
index 0545b9f55a2930cf14980fb88ae5a454ab5b8451..41d0f0ec23293c9e2efc197ac2f6eda830da7dcc 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/SnarkManager.java
@@ -533,9 +533,9 @@ public class SnarkManager implements Snark.CompleteListener {
         File f = new File(filename);
         if (!dontAutoStart && shouldAutoStart()) {
             torrent.startTorrent();
-            addMessage(_("Torrent added and started: \"{0}\"", f.getName()));
+            addMessage(_("Torrent added and started: \"{0}\"", torrent.storage.getBaseName()));
         } else {
-            addMessage(_("Torrent added: \"{0}\"", f.getName()));
+            addMessage(_("Torrent added: \"{0}\"", torrent.storage.getBaseName()));
         }
     }
     
@@ -742,8 +742,14 @@ public class SnarkManager implements Snark.CompleteListener {
                 // I2PServerSocket.accept() call properly?)
                 ////_util.
             }
+            String name;
+            if (torrent.storage != null) {
+                name = torrent.storage.getBaseName();
+            } else {
+                name = sfile.getName();
+            }
             if (!wasStopped)
-                addMessage(_("Torrent stopped: \"{0}\"", sfile.getName()));
+                addMessage(_("Torrent stopped: \"{0}\"", name));
         }
         return torrent;
     }
@@ -756,9 +762,14 @@ public class SnarkManager implements Snark.CompleteListener {
         if (torrent != null) {
             File torrentFile = new File(filename);
             torrentFile.delete();
-            if (torrent.storage != null)
+            String name;
+            if (torrent.storage != null) {
                 removeTorrentStatus(torrent.storage.getMetaInfo());
-            addMessage(_("Torrent removed: \"{0}\"", torrentFile.getName()));
+                name = torrent.storage.getBaseName();
+            } else {
+                name = torrentFile.getName();
+            }
+            addMessage(_("Torrent removed: \"{0}\"", name));
         }
     }
     
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 b9f06c8778dbcd7158b2169d155cd4d54138f172..f49178b0f51881f88ba0aec82f4fc6698a6ba07a 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/web/I2PSnarkServlet.java
@@ -163,7 +163,7 @@ public class I2PSnarkServlet extends Default {
         
         String peerParam = req.getParameter("p");
         String peerString;
-        if (peerParam == null) {
+        if (peerParam == null || !_manager.util().connected()) {
             peerString = "";
         } else {
             peerString = "?p=" + peerParam;
@@ -248,6 +248,9 @@ public class I2PSnarkServlet extends Default {
             out.write(uri);
             out.write("\" method=\"POST\">\n");
             out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
+            // don't lose peer setting
+            if (peerParam != null)
+                out.write("<input type=\"hidden\" name=\"p\" value=\"" + peerParam + "\" >\n");
         }
         out.write(TABLE_HEADER);
         out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/status.png\"");
@@ -435,11 +438,12 @@ public class I2PSnarkServlet extends Default {
             if (torrent != null) {
                 byte infoHash[] = Base64.decode(torrent);
                 if ( (infoHash != null) && (infoHash.length == 20) ) { // valid sha1
-                    for (Iterator iter = _manager.listTorrentFiles().iterator(); iter.hasNext(); ) {
-                        String name = (String)iter.next();
+                    for (String name : _manager.listTorrentFiles()) {
                         Snark snark = _manager.getTorrent(name);
                         if ( (snark != null) && (DataHelper.eq(infoHash, snark.meta.getInfoHash())) ) {
                             snark.startTorrent();
+                            if (snark.storage != null)
+                                name = snark.storage.getBaseName();
                             _manager.addMessage(_("Starting up torrent {0}", name));
                             break;
                         }
@@ -1001,6 +1005,10 @@ public class I2PSnarkServlet extends Default {
         out.write("<form action=\"" + uri + "\" method=\"POST\">\n");
         out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
         out.write("<input type=\"hidden\" name=\"action\" value=\"Add\" >\n");
+        // don't lose peer setting
+        String peerParam = req.getParameter("p");
+        if (peerParam != null)
+            out.write("<input type=\"hidden\" name=\"p\" value=\"" + peerParam + "\" >\n");
         out.write("<div class=\"addtorrentsection\"><span class=\"snarkConfigTitle\">");
         out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/add.png\">");
         out.write(_("Add Torrent"));
@@ -1036,6 +1044,10 @@ public class I2PSnarkServlet extends Default {
         out.write("<form action=\"" + uri + "\" method=\"POST\">\n");
         out.write("<input type=\"hidden\" name=\"nonce\" value=\"" + _nonce + "\" >\n");
         out.write("<input type=\"hidden\" name=\"action\" value=\"Create\" >\n");
+        // don't lose peer setting
+        String peerParam = req.getParameter("p");
+        if (peerParam != null)
+            out.write("<input type=\"hidden\" name=\"p\" value=\"" + peerParam + "\" >\n");
         out.write("<span class=\"snarkConfigTitle\">");
         out.write("<img border=\"0\" src=\"/themes/snark/ubergine/images/create.png\">");
         out.write(_("Create Torrent"));
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHandler.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHandler.java
index 68f730e963e97f26af65ca1ed8afc2cc362424cc..c43cb1eb52947608db3048c0f19ef2e0d74abd25 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHandler.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigTunnelsHandler.java
@@ -14,7 +14,6 @@ import net.i2p.util.Log;
  *
  */
 public class ConfigTunnelsHandler extends FormHandler {
-    private Log configTunnel_log;
     private Map _settings;
     private boolean _shouldSave;
     
@@ -44,11 +43,10 @@ public class ConfigTunnelsHandler extends FormHandler {
      *
      */
     private void saveChanges() {
-        configTunnel_log = _context.logManager().getLog(ConfigTunnelsHandler.class);
         boolean saveRequired = false;
         
-        if (configTunnel_log.shouldLog(Log.DEBUG))
-            configTunnel_log.debug("Saving changes, with props = " + _settings + ".");
+        if (_log.shouldLog(Log.DEBUG))
+            _log.debug("Saving changes, with props = " + _settings + ".");
         
         int updated = 0;
         int index = 0;
@@ -111,16 +109,16 @@ public class ConfigTunnelsHandler extends FormHandler {
             }
             
             if ("exploratory".equals(poolName)) {
-                if (configTunnel_log.shouldLog(Log.DEBUG)) {
-                    configTunnel_log.debug("Inbound exploratory settings: " + in);
-                    configTunnel_log.debug("Outbound exploratory settings: " + out);
+                if (_log.shouldLog(Log.DEBUG)) {
+                    _log.debug("Inbound exploratory settings: " + in);
+                    _log.debug("Outbound exploratory settings: " + out);
                 }
                 _context.tunnelManager().setInboundSettings(in);
                 _context.tunnelManager().setOutboundSettings(out);
             } else {
-                if (configTunnel_log.shouldLog(Log.DEBUG)) {
-                    configTunnel_log.debug("Inbound settings for " + client.toBase64() + ": " + in);
-                    configTunnel_log.debug("Outbound settings for " + client.toBase64() + ": " + out);
+                if (_log.shouldLog(Log.DEBUG)) {
+                    _log.debug("Inbound settings for " + client.toBase64() + ": " + in);
+                    _log.debug("Outbound settings for " + client.toBase64() + ": " + out);
                 }
                 _context.tunnelManager().setInboundSettings(client, in);
                 _context.tunnelManager().setOutboundSettings(client, out);
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java
index fbb9bad4fff763811df80235625798a5322fb3e1..845bb66a03e378bb6233da5ddede4f72df3c3e6d 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/ConfigUIHelper.java
@@ -46,10 +46,11 @@ public class ConfigUIHelper extends HelperBase {
          return rv;
     }
 
-    private static final String langs[] = {"de", "en", "es", "fr", "nl", "ru", "sv", "zh"};
-    private static final String flags[] = {"de", "us", "es", "fr", "nl", "ru", "se", "cn"};
+    private static final String langs[] = {"de", "en", "es", "fr", "nl", "pt", "ru", "sv", "zh"};
+    private static final String flags[] = {"de", "us", "es", "fr", "nl", "pt", "ru", "se", "cn"};
     private static final String xlangs[] = {_x("German"), _x("English"), _x("Spanish"),_x("French"),
-                                            _x("Dutch"), _x("Russian"), _x("Swedish"), _x("Chinese")};
+                                            _x("Dutch"), _x("Portuguese"), _x("Russian"),
+                                            _x("Swedish"), _x("Chinese")};
 
     /** todo sort by translated string */
     public String getLangSettings() {
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
index 6958b350e9b2f2ccaf2e4126758ab75137f659af..c44b34f39afd86135d88707f505f65578c5749d7 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/PluginStarter.java
@@ -50,6 +50,7 @@ public class PluginStarter implements Runnable {
     private static Map<String, ThreadGroup> pluginThreadGroups = new ConcurrentHashMap<String, ThreadGroup>();   // one thread group per plugin (map key=plugin name)
     private static Map<String, Collection<Job>> pluginJobs = new ConcurrentHashMap<String, Collection<Job>>();
     private static Map<String, ClassLoader> _clCache = new ConcurrentHashMap();
+    private static Map<String, Collection<String>> pluginWars = new ConcurrentHashMap<String, Collection<String>>();
 
     public PluginStarter(RouterContext ctx) {
         _context = ctx;
@@ -125,6 +126,8 @@ public class PluginStarter implements Runnable {
             File webappDir = new File(consoleDir, "webapps");
             String fileNames[] = webappDir.list(RouterConsoleRunner.WarFilenameFilter.instance());
             if (fileNames != null) {
+                if(!pluginWars.containsKey(appName))
+                    pluginWars.put(appName, new ConcurrentHashSet<String>());
                 for (int i = 0; i < fileNames.length; i++) {
                     try {
                         String warName = fileNames[i].substring(0, fileNames[i].lastIndexOf(".war"));
@@ -139,6 +142,7 @@ public class PluginStarter implements Runnable {
                             //log.error("Starting webapp: " + warName);
                             String path = new File(webappDir, fileNames[i]).getCanonicalPath();
                             WebAppStarter.startWebApp(ctx, server, warName, path);
+                            pluginWars.get(appName).add(warName);
                         }
                     } catch (IOException ioe) {
                         log.error("Error resolving '" + fileNames[i] + "' in '" + webappDir, ioe);
@@ -215,6 +219,7 @@ public class PluginStarter implements Runnable {
         // stop console webapps in console/webapps
         Server server = WebAppStarter.getConsoleServer();
         if (server != null) {
+        /*
             File consoleDir = new File(pluginDir, "console");
             Properties props = RouterConsoleRunner.webAppProperties(consoleDir.getAbsolutePath());
             File webappDir = new File(consoleDir, "webapps");
@@ -228,6 +233,13 @@ public class PluginStarter implements Runnable {
                     WebAppStarter.stopWebApp(server, warName);
                 }
             }
+        */
+            Iterator <String> wars = pluginWars.get(appName).iterator();
+            while (wars.hasNext()) {
+                String warName = wars.next();
+                WebAppStarter.stopWebApp(server, warName);
+            }
+            pluginWars.get(appName).clear();
         }
 
         // remove summary bar link
@@ -487,10 +499,25 @@ public class PluginStarter implements Runnable {
                     isJobRunning = true;
                     break;
                 }
+        boolean isWarRunning = false;
+        if(pluginWars.containsKey(pluginName)) {
+            Iterator <String> it = pluginWars.get(pluginName).iterator();
+            while(it.hasNext() && !isWarRunning) {
+                String warName = it.next();
+                if(WebAppStarter.isWebAppRunning(warName)) {
+                    isWarRunning = true;
+                }
+            }
+        }
 
         if (log.shouldLog(Log.DEBUG))
-            log.debug("plugin name = <" + pluginName + ">; threads running? " + isClientThreadRunning(pluginName) + "; webapp runing? " + WebAppStarter.isWebAppRunning(pluginName) + "; jobs running? " + isJobRunning);
-        return isClientThreadRunning(pluginName) || WebAppStarter.isWebAppRunning(pluginName) || isJobRunning;
+            log.debug("plugin name = <" + pluginName + ">; threads running? " + isClientThreadRunning(pluginName) + "; webapp runing? " + isWarRunning + "; jobs running? " + isJobRunning);
+        return isClientThreadRunning(pluginName) || isWarRunning || isJobRunning;
+        //
+        //if (log.shouldLog(Log.DEBUG))
+        //    log.debug("plugin name = <" + pluginName + ">; threads running? " + isClientThreadRunning(pluginName) + "; webapp runing? " + WebAppStarter.isWebAppRunning(pluginName) + "; jobs running? " + isJobRunning);
+        //return isClientThreadRunning(pluginName) || WebAppStarter.isWebAppRunning(pluginName) || isJobRunning;
+        //
     }
     
     /**
diff --git a/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java b/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java
index 72c93330e23d2d78d085556990bd8b84fa8504bc..f1306a2c1f9a7db4ddf332dec231c02636910b81 100644
--- a/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java
+++ b/apps/routerconsole/java/src/net/i2p/router/web/StatSummarizer.java
@@ -6,6 +6,7 @@ import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.StringTokenizer;
+import java.util.concurrent.Semaphore;
 
 import net.i2p.router.RouterContext;
 import net.i2p.stat.Rate;
@@ -20,17 +21,20 @@ import org.jrobin.graph.RrdGraphDef;
  *
  */
 public class StatSummarizer implements Runnable {
-    private RouterContext _context;
-    private Log _log;
+    private final RouterContext _context;
+    private final Log _log;
     /** list of SummaryListener instances */
-    private List _listeners;
+    private final List<SummaryListener> _listeners;
     private static StatSummarizer _instance;
+    private static final int MAX_CONCURRENT_PNG = 3;
+    private final Semaphore _sem;
     
     public StatSummarizer() {
         _context = (RouterContext)RouterContext.listContexts().get(0); // fuck it, only summarize one per jvm
         _log = _context.logManager().getLog(getClass());
         _listeners = new ArrayList(16);
         _instance = this;
+        _sem = new Semaphore(MAX_CONCURRENT_PNG, true);
     }
     
     public static StatSummarizer instance() { return _instance; }
@@ -44,7 +48,7 @@ public class StatSummarizer implements Runnable {
     }
     
     /** list of SummaryListener instances */
-    List getListeners() { return _listeners; }
+    List<SummaryListener> getListeners() { return _listeners; }
     
     private static final String DEFAULT_DATABASES = "bw.sendRate.60000" +
                                                     ",bw.recvRate.60000" +
@@ -77,31 +81,32 @@ public class StatSummarizer implements Runnable {
              ( (spec != null) && (oldSpecs != null) && (oldSpecs.equals(spec))) )
             return oldSpecs;
         
-        List old = parseSpecs(oldSpecs);
-        List newSpecs = parseSpecs(spec);
+        List<Rate> old = parseSpecs(oldSpecs);
+        List<Rate> newSpecs = parseSpecs(spec);
         
         // remove old ones
-        for (int i = 0; i < old.size(); i++) {
-            Rate r = (Rate)old.get(i);
+        for (Rate r : old) {
             if (!newSpecs.contains(r))
                 removeDb(r);
         }
         // add new ones
         StringBuilder buf = new StringBuilder();
-        for (int i = 0; i < newSpecs.size(); i++) {
-            Rate r = (Rate)newSpecs.get(i);
+        boolean comma = false;
+        for (Rate r : newSpecs) {
             if (!old.contains(r))
                 addDb(r);
-            buf.append(r.getRateStat().getName()).append(".").append(r.getPeriod());
-            if (i + 1 < newSpecs.size())
+            if (comma)
                 buf.append(',');
+            else
+                comma = true;
+            buf.append(r.getRateStat().getName()).append(".").append(r.getPeriod());
         }
         return buf.toString();
     }
     
     private void removeDb(Rate r) {
         for (int i = 0; i < _listeners.size(); i++) {
-            SummaryListener lsnr = (SummaryListener)_listeners.get(i);
+            SummaryListener lsnr = _listeners.get(i);
             if (lsnr.getRate().equals(r)) {
                 _listeners.remove(i);
                 lsnr.stopListening();
@@ -115,16 +120,40 @@ public class StatSummarizer implements Runnable {
         lsnr.startListening();
         //System.out.println("Start listening for " + r.getRateStat().getName() + ": " + r.getPeriod());
     }
+
     public boolean renderPng(Rate rate, OutputStream out) throws IOException { 
         return renderPng(rate, out, -1, -1, false, false, false, false, -1, true); 
     }
-    public boolean renderPng(Rate rate, OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, boolean showCredit) throws IOException {
+
+    /**
+     *  This does the single data graphs.
+     *  For the two-data bandwidth graph see renderRatePng().
+     *  Synchronized to conserve memory.
+     *  @return success
+     */
+    public boolean renderPng(Rate rate, OutputStream out, int width, int height, boolean hideLegend,
+                                          boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount,
+                                          boolean showCredit) throws IOException {
+        try {
+            try {
+                _sem.acquire();
+            } catch (InterruptedException ie) {}
+            return locked_renderPng(rate, out, width, height, hideLegend, hideGrid, hideTitle, showEvents,
+                                    periodCount, showCredit);
+        } finally {
+                _sem.release();
+        }
+    }
+
+    private boolean locked_renderPng(Rate rate, OutputStream out, int width, int height, boolean hideLegend,
+                                          boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount,
+                                          boolean showCredit) throws IOException {
         if (width > GraphHelper.MAX_X)
             width = GraphHelper.MAX_X;
         if (height > GraphHelper.MAX_Y)
             height = GraphHelper.MAX_Y;
         for (int i = 0; i < _listeners.size(); i++) {
-            SummaryListener lsnr = (SummaryListener)_listeners.get(i);
+            SummaryListener lsnr = _listeners.get(i);
             if (lsnr.getRate().equals(rate)) {
                 lsnr.renderPng(out, width, height, hideLegend, hideGrid, hideTitle, showEvents, periodCount, showCredit);
                 return true;
@@ -132,13 +161,15 @@ public class StatSummarizer implements Runnable {
         }
         return false;
     }
+
     public boolean renderPng(OutputStream out, String templateFilename) throws IOException {
         SummaryRenderer.render(_context, out, templateFilename);
         return true;
     }
+
     public boolean getXML(Rate rate, OutputStream out) throws IOException {
         for (int i = 0; i < _listeners.size(); i++) {
-            SummaryListener lsnr = (SummaryListener)_listeners.get(i);
+            SummaryListener lsnr = _listeners.get(i);
             if (lsnr.getRate().equals(rate)) {
                 lsnr.getData().exportXml(out);
                 out.write(("<!-- Rate: " + lsnr.getRate().getRateStat().getName() + " for period " + lsnr.getRate().getPeriod() + " -->\n").getBytes());
@@ -152,8 +183,26 @@ public class StatSummarizer implements Runnable {
     /**
      *  This does the two-data bandwidth graph only.
      *  For all other graphs see SummaryRenderer
+     *  Synchronized to conserve memory.
+     *  @return success
      */
-    public boolean renderRatePng(OutputStream out, int width, int height, boolean hideLegend, boolean hideGrid, boolean hideTitle, boolean showEvents, int periodCount, boolean showCredit) throws IOException {
+    public boolean renderRatePng(OutputStream out, int width, int height, boolean hideLegend,
+                                              boolean hideGrid, boolean hideTitle, boolean showEvents,
+                                              int periodCount, boolean showCredit) throws IOException {
+        try {
+            try {
+                _sem.acquire();
+            } catch (InterruptedException ie) {}
+            return locked_renderRatePng(out, width, height, hideLegend, hideGrid, hideTitle, showEvents,
+                                        periodCount, showCredit);
+        } finally {
+                _sem.release();
+        }
+    }
+
+    private boolean locked_renderRatePng(OutputStream out, int width, int height, boolean hideLegend,
+                                              boolean hideGrid, boolean hideTitle, boolean showEvents,
+                                              int periodCount, boolean showCredit) throws IOException {
         long end = _context.clock().now() - 60*1000;
         if (width > GraphHelper.MAX_X)
             width = GraphHelper.MAX_X;
@@ -230,9 +279,9 @@ public class StatSummarizer implements Runnable {
      * @param specs statName.period,statName.period,statName.period
      * @return list of Rate objects
      */
-    private List parseSpecs(String specs) {
+    private List<Rate> parseSpecs(String specs) {
         StringTokenizer tok = new StringTokenizer(specs, ",");
-        List rv = new ArrayList();
+        List<Rate> rv = new ArrayList();
         while (tok.hasMoreTokens()) {
             String spec = tok.nextToken();
             int split = spec.lastIndexOf('.');
diff --git a/apps/routerconsole/jsp/logs.jsp b/apps/routerconsole/jsp/logs.jsp
index 75f052e9b22c3136aa20e926e2605c09f3242fa5..019564bbe3f2d39e7a15fc79cf23f89cc4bd7008 100644
--- a/apps/routerconsole/jsp/logs.jsp
+++ b/apps/routerconsole/jsp/logs.jsp
@@ -10,7 +10,11 @@
 <h1><%=intl._("I2P Router Logs")%></h1>
 <div class="main" id="main">
  <div class="joblog"><h3><%=intl._("I2P Version & Running Environment")%></h3><a name="version"> </a>
-<p><%=intl._("Please report bugs on <a href=\"http://trac.i2p2.i2p/newticket\">trac.i2p2.i2p</a> or <a href=\"http://trac.i2p2.de/newticket\">trac.i2p2.de</a>.")%>
+<p>
+<% /* note to translators - both parameters are URLs */
+%><%=intl._("Please report bugs on {0} or {1}.",
+          "<a href=\"http://trac.i2p2.i2p/newticket\">trac.i2p2.i2p</a>",
+          "<a href=\"http://trac.i2p2.de/newticket\">trac.i2p2.de</a>")%>
 <%=intl._("You may use the username \"guest\" and password \"guest\" if you do not wish to register.")%>
 <p><i><%=intl._("Please include this information in bug reports")%>:</i>
  <p>
diff --git a/core/java/src/net/i2p/data/Base64.java b/core/java/src/net/i2p/data/Base64.java
index b5e03b03c7bf036f3cfe7b27b950c4e674a78c12..fe730af6b4a0349e527f7347d32e094c16aeaa6c 100644
--- a/core/java/src/net/i2p/data/Base64.java
+++ b/core/java/src/net/i2p/data/Base64.java
@@ -80,7 +80,9 @@ public class Base64 {
     }
 
     /**
+     *  Decodes data from Base64 notation.
      *  @param s Base 64 encoded string using the I2P alphabet A-Z, a-z, 0-9, -, ~
+     *  @return the decoded data, null on error
      */
     public static byte[] decode(String s) {
         return safeDecode(s, false);
@@ -234,6 +236,7 @@ public class Base64 {
         System.out.println("or    : Base64 test");
     }
 
+/*******
     private static void test() {
         String orig = "you smell";
         String encoded = Base64.encode(orig.getBytes());
@@ -255,6 +258,7 @@ public class Base64 {
         else
             throw new RuntimeException("D(E([all bytes])) != [all bytes]!!!");
     }
+*******/
 
     /* ********  E N C O D I N G   M E T H O D S  ******** */
 
diff --git a/core/java/src/net/i2p/data/SimpleDataStructure.java b/core/java/src/net/i2p/data/SimpleDataStructure.java
index 16a2ec88e1220e82adea0e32a57a9a1d987ff144..96c1585c581bdb76097bb284062fb3381aacc254 100644
--- a/core/java/src/net/i2p/data/SimpleDataStructure.java
+++ b/core/java/src/net/i2p/data/SimpleDataStructure.java
@@ -82,10 +82,20 @@ public abstract class SimpleDataStructure extends DataStructureImpl {
         return Base64.encode(_data);
     }
 
+    /**
+     * Sets the data.
+     * @throws DataFormatException if decoded data is not the legal number of bytes or on decoding error
+     */
     @Override
     public void fromBase64(String data) throws DataFormatException {
         if (data == null) throw new DataFormatException("Null data passed in");
-        _data = Base64.decode(data);
+        byte[] d = Base64.decode(data);
+        if (d == null)
+            throw new DataFormatException("Bad Base64 encoded data");
+        if (d.length != _length)
+            throw new DataFormatException("Bad decoded data length, expected " + _length + " got " + d.length);
+        // call setData() instead of _data = data in case overridden
+        setData(d);
     }
 
     /** @return the SHA256 hash of the byte array, or null if the data is null */
@@ -106,7 +116,7 @@ public abstract class SimpleDataStructure extends DataStructureImpl {
 
     /**
      * Overridden for efficiency.
-     * Does the same thing as getData() but null not allowed.
+     * Does the same thing as setData() but null not allowed.
      * @param data non-null
      * @throws DataFormatException if null or wrong length
      */
@@ -114,7 +124,8 @@ public abstract class SimpleDataStructure extends DataStructureImpl {
     public void fromByteArray(byte data[]) throws DataFormatException {
         if (data == null) throw new DataFormatException("Null data passed in");
         if (data.length != _length) throw new DataFormatException("Bad data length");
-        _data = data;
+        // call setData() instead of _data = data in case overridden
+        setData(data);
     }
 
     @Override
diff --git a/debian/changelog b/debian/changelog
index 1e92507d80a78e1ec89dd792e020886e3a90b931..110bae03b31d1d150edc9c4081af5fa53a38fcc6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+i2p (0.8.1-4) all; urgency=low
+  * I2P 0.8.1-6
+  * Closes: #448638
+ -- Hungry Hobo <HungryHobo@i2pmail.org>  Mon, 24 Nov 2010 17:14:57 +0000
+
+i2p (0.8.1-3) all; urgency=low
+  * I2P 0.8.1-3
+ -- Hungry Hobo <HungryHobo@i2pmail.org>  Mon, 21 Nov 2010 17:14:57 +0000
+
 i2p (0.8.1) all; urgency=low
   * Speedups
   * Bugfixes
diff --git a/debian/makerepo.sh b/debian/makerepo.sh
index ad845f31dfcd1e37a29a9a6f6e5aabd732054b83..4f1078627008bdd39d70546ed00e4a20caa7ff19 100755
--- a/debian/makerepo.sh
+++ b/debian/makerepo.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 # This script creates a Debian repository in ${DIR} using the reprepro tool.
 # The packages are signed with the key referenced in the newest changelog entry.
 
@@ -9,9 +9,7 @@ DIR=./repo
 CONFDIR=conf
 CONFFILE=${CONFDIR}/distributions
 
-SIGNER=`parsechangelog --file changelog | grep Maintainer | cut -d: -f2`
-SIGNER=${SIGNER//^ /}
-SIGNER=`echo ${SIGNER} | cut -d\  -f1`
+SIGNER=`parsechangelog --file changelog | grep Maintainer | cut -d\< -f2 | cut -d\> -f1`
 KEYID=`gpg --list-keys "${SIGNER}" | cut -d: -f2 | grep -w pub | cut -d/ -f2 | cut -d\  -f1`
 echo Using signing key: ${SIGNER}
 echo Key ID: ${KEYID}
diff --git a/history.txt b/history.txt
index 398b6ca0c8fa803fc677d92605ae817e97399536..b9ff2738bb1e7acd1bb9dc30f2ac6fbd415015aa 100644
--- a/history.txt
+++ b/history.txt
@@ -1,3 +1,29 @@
+2010-11-24 zzz
+    * configui: Add .pt
+    * configtunnels: Log cleanup
+    * graphs: Synch to conserve memory; cleanup
+    * i2psnark:
+      - Prevent dup requests during end game
+        (ticket 331 - thanks sponge and Oct!)
+      - POST parameter tweaks
+      - Message cleanup
+    * logs: Add trac login hint
+    * Router:
+      - Save some info to config file when installing or updating
+      - Remove global lock on accessing config
+      - Add global lock on reading/writing config file
+    * SimpleDataStructure: Fix problem in fromBase64() that
+      manifested itself as a configtunnels.jsp bug
+
+2010-11-24 sponge
+    * Slackware, fix rc.i2p, bad logic.
+
+2010-11-24 sponge
+    * Plugin: ticket 104 Fix webapp isRunning to check ALL webapps.
+      The only defecency is that if one is running, that it considers the
+      entire pliugin to be running. I'm not sure if that is a good thing
+      or a bad thing, but the other code checks threads that way.
+
 2010-11-22 zzz
     * Addressbook: Fix rename error on Windows (tkt 323 - thanks RN!)
     * build.xml: Cleanup, fix distclean error in older ants.
diff --git a/installer/resources/readme/readme.html b/installer/resources/readme/readme.html
index 9e1f5ed1da257d65960efcfd395c849c45985344..a1f881f13076fb615de3c289dd4a933b06670def 100644
--- a/installer/resources/readme/readme.html
+++ b/installer/resources/readme/readme.html
@@ -6,7 +6,7 @@
     <a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
     <a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a> 
     <a href="/index.jsp?lang=es"><img src="/flags.jsp?c=es" title="Espa&ntilde;ol" alt="Espa&ntilde;ol"></a> 
-    <a href="/index.jsp?lang=br"><img src="/flags.jsp?c=br" title="Português" alt="Português"></a> 
+    <a href="/index.jsp?lang=pt"><img src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
     <a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
     <a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
     <a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
diff --git a/installer/resources/readme/readme_de.html b/installer/resources/readme/readme_de.html
index b4188c9b1fd654ddbb53f9c14c656c5e30deadf2..1b3ba8e1aa80e36eeb321dc4b0c408350c5724ad 100644
--- a/installer/resources/readme/readme_de.html
+++ b/installer/resources/readme/readme_de.html
@@ -6,7 +6,7 @@
     <a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a>
     <a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a>
     <a href="/index.jsp?lang=es"><img src="/flags.jsp?c=es" title="Espa&ntilde;ol" alt="Espa&ntilde;ol"></a>
-    <a href="/index.jsp?lang=br"><img src="/flags.jsp?c=br" title="Português" alt="Português"></a> 
+    <a href="/index.jsp?lang=pt"><img src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
     <a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a>
     <a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a>
     <a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a>
diff --git a/installer/resources/readme/readme_es.html b/installer/resources/readme/readme_es.html
index 286493a9a711b8487cfb7eec3c775a3bf7870e02..2916cfed8a5a11f41cd0b1b4e90f6c99cca2de43 100644
--- a/installer/resources/readme/readme_es.html
+++ b/installer/resources/readme/readme_es.html
@@ -6,7 +6,7 @@
 	<a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
 	<a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a> 
 	<a href="/index.jsp?lang=es"><img src="/flags.jsp?c=es" title="Espa&ntilde;ol" alt="Espa&ntilde;ol"></a> 
-	<a href="/index.jsp?lang=br"><img src="/flags.jsp?c=br" title="Português" alt="Português"></a> 
+	<a href="/index.jsp?lang=pt"><img src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
 	<a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
 	<a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
 	<a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
diff --git a/installer/resources/readme/readme_fr.html b/installer/resources/readme/readme_fr.html
index 5deef64443f4b5d75069eac36ae1894d25003976..077479b3ed17a0a303aaba25a05d85758613ec8d 100644
--- a/installer/resources/readme/readme_fr.html
+++ b/installer/resources/readme/readme_fr.html
@@ -6,7 +6,7 @@
 	<a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
 	<a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a> 
 	<a href="/index.jsp?lang=es"><img src="/flags.jsp?c=es" title="Espa&ntilde;ol" alt="Espa&ntilde;ol"></a> 
-	<a href="/index.jsp?lang=br"><img src="/flags.jsp?c=br" title="Português" alt="Português"></a> 
+	<a href="/index.jsp?lang=pt"><img src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
 	<a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
 	<a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
 	<a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
diff --git a/installer/resources/readme/readme_nl.html b/installer/resources/readme/readme_nl.html
index cdb19a47bc022ea03fc0a2ba106a20d0615142ba..bd5938ef27ac358c45ae0006ebb322c9dcb2d013 100644
--- a/installer/resources/readme/readme_nl.html
+++ b/installer/resources/readme/readme_nl.html
@@ -6,7 +6,7 @@
 	<a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
 	<a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a> 
 	<a href="/index.jsp?lang=es"><img src="/flags.jsp?c=es" title="Espa&ntilde;ol" alt="Espa&ntilde;ol"></a> 
-	<a href="/index.jsp?lang=br"><img src="/flags.jsp?c=br" title="Português" alt="Português"></a> 
+	<a href="/index.jsp?lang=pt"><img src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
 	<a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
 	<a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
 	<a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
diff --git a/installer/resources/readme/readme_br.html b/installer/resources/readme/readme_pt.html
similarity index 99%
rename from installer/resources/readme/readme_br.html
rename to installer/resources/readme/readme_pt.html
index 2e3f581cf3b7aada8bcefa6694ca2980cbfa9be6..dce922e8b12dc24804331741d668eab5a7da4a66 100644
--- a/installer/resources/readme/readme_br.html
+++ b/installer/resources/readme/readme_pt.html
@@ -6,7 +6,7 @@
 	<a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
 	<a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a> 
 	<a href="/index.jsp?lang=es"><img src="/flags.jsp?c=es" title="Espa&ntilde;ol" alt="Espa&ntilde;ol"></a> 
-	<a href="/index.jsp?lang=br"><img src="/flags.jsp?c=br" title="Português" alt="Português"></a> 
+	<a href="/index.jsp?lang=pt"><img src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
 	<a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
 	<a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
 	<a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
diff --git a/installer/resources/readme/readme_ru.html b/installer/resources/readme/readme_ru.html
index afaabf8c202319b9949a753895a2a93fe97adf42..712af234842bc7d14aea314e5dde30e54c13535e 100644
--- a/installer/resources/readme/readme_ru.html
+++ b/installer/resources/readme/readme_ru.html
@@ -5,7 +5,7 @@
     <a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
     <a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Français" alt="Français"></a> 
     <a href="/index.jsp?lang=es"><img src="/flags.jsp?c=es" title="Espa&ntilde;ol" alt="Espa&ntilde;ol"></a> 
-    <a href="/index.jsp?lang=br"><img src="/flags.jsp?c=br" title="Português" alt="Português"></a> 
+    <a href="/index.jsp?lang=pt"><img src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
     <a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
     <a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
     <a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
diff --git a/installer/resources/readme/readme_sv.html b/installer/resources/readme/readme_sv.html
index f7856d9a3bd608a2e41f9f231013083f4ecf155e..e5c3b9ecdd72b2dd4fc42c7cdf301ec3a4c44fc6 100644
--- a/installer/resources/readme/readme_sv.html
+++ b/installer/resources/readme/readme_sv.html
@@ -6,7 +6,7 @@
 	<a href="/index.jsp?lang=de"><img src="/flags.jsp?c=de" title="Deutsch" alt="Deutsch"></a> 
 	<a href="/index.jsp?lang=fr"><img src="/flags.jsp?c=fr" title="Fran&ccedil;ais" alt="Fran&ccedil;ais"></a> 
 	<a href="/index.jsp?lang=es"><img src="/flags.jsp?c=es" title="Espa&ntilde;ol" alt="Espa&ntilde;ol"></a> 
-	<a href="/index.jsp?lang=br"><img src="/flags.jsp?c=br" title="Português" alt="Português"></a> 
+	<a href="/index.jsp?lang=pt"><img src="/flags.jsp?c=pt" title="Português" alt="Português"></a> 
 	<a href="/index.jsp?lang=nl"><img src="/flags.jsp?c=nl" title="Nederlands" alt="Nederlands"></a> 
 	<a href="/index.jsp?lang=ru"><img src="/flags.jsp?c=ru" title="Русский" alt="Русский"></a> 
 	<a href="/index.jsp?lang=sv"><img src="/flags.jsp?c=se" title="Svenska" alt="Svenska"></a></div>
diff --git a/installer/resources/themes/console/classic/console.css b/installer/resources/themes/console/classic/console.css
index 5da45d2afd04c396fda4efce221f8a0df1547caf..d4944facefd9d20a6ca67034f4302bc0ee4169a7 100644
--- a/installer/resources/themes/console/classic/console.css
+++ b/installer/resources/themes/console/classic/console.css
@@ -1,11 +1,10 @@
-/* I2P Theme: Classic */
-/* Description: Classic theme, loosely based on duck's original */
-/* Optimized for less capable browsers and system specifications */
+/* I2P Theme: Classic (aka corporat) */
+/* I2P Description: Light blue "classic" I2P theme; optimized for less capable browsers and system specifications. */
 /* Author: dr|z3d */
 
 
 body {
-     margin: 2px 0 0 2px;
+     margin: 5px 3px 5px 6px;
      padding: 0;
      text-align: left;
      background: #bbf;
@@ -28,6 +27,8 @@ pre {
      padding-top: 10px;
 }
 
+/* Sidepanel for proxy errors */
+
 div.logo {
      float: left;
      position-relative: top 20px ;
@@ -37,9 +38,7 @@ div.logo {
      text-align: center;
      border: 5px solid #ddf;
      background-color: #eef;
-     -moz-border-radius: 15px;
      -moz-box-shadow: inset 0px 0px 0px 2px #99f;
-     -khtml-border-radius: 15px;
      -khtml-box-shadow: inset 0px 0px 0px 2px #99f;
 }
 
@@ -65,6 +64,8 @@ div.logo a:hover {
      color: #900;
 }
 
+/* HTTP Proxy warning Main box */
+
 div.warning {
      margin: 20px 20px 10px 260px;
      padding: 0px 20px 20px 75px;
@@ -75,9 +76,7 @@ div.warning {
      background-image:url("../images/itoopie_sm.png");     
      background-position: 12px center;
      background-repeat:no-repeat;
-     -moz-border-radius: 15px;
      -moz-box-shadow: inset 0px 0px 0px 2px #f60;
-     -kthml-border-radius: 15px;
      -khtml-box-shadow: inset 0px 0px 0px 2px #f60;
 }
 
@@ -92,7 +91,7 @@ div.warning a:visited{
 
 div.warning a:hover{
      color: #d30;
-  text-shadow: 0px 0px 1px rgba(255, 96, 0, 0.7);
+     text-shadow: 0px 0px 1px rgba(255, 96, 0, 0.7);
 }
 
 div.warning a:active{
@@ -107,25 +106,32 @@ div.warning hr {
      margin: 5px 0;
 }
 
+div.warning h3 {
+     border: 0;
+     border-bottom: 5px solid #fb7;
+     padding-bottom: 10px;
+     background: #ffd;
+     padding-left: 0;
+}
+
 /* console error messages */
 
 div.sorry {
      padding: 20px;
      background: #ddf;
-     margin: -2px 1px 0 195px;
-     border: 5px solid #bbf;
+     margin: -1px 1px 0 200px;
+     border: 1px solid #89f;
      text-align: justify;
-     -moz-box-shadow: inset 0px 0px 0px 1px #d00;
      word-wrap: break-word;
      font-weight: bold;
      color: #001;
 }
 
 div.sorry hr {
-     color: #001;
-     background: #001;
+     color: #89f;
+     background: #89f;
      height: 1px;
-     border: 1px solid #001;
+     border: 0px solid #89f;
      margin: 10px 0;
 }
 
@@ -135,9 +141,11 @@ div.toolbar {
      display: none !important;
 }
 
+/* Side panel */
+
 div.routersummaryouter {
      float: left; 
-     width: 200px;
+     width: 193px;
      margin: 0;
      padding: 0;
      border: 0;
@@ -146,16 +154,16 @@ div.routersummaryouter {
 
 div.routersummary {
      background: #ddf;
-     width: 185px;
+     width: 193px;
      color: inherit;
      margin: 0;
      padding: 10px 1px 7px 1px;
      text-align: center !important;
-     border: 5px solid #bbf;
-     font-size: 9pt;
+     border: 1px solid #89f;
+     border-bottom: 1px solid #89f;
+     border-right: 1px solid #89f;
      word-wrap: break-word;
-     font: 9pt/125%;
-     -moz-box-shadow: inset 0px 0px 0px 1px #99f;
+     font: 9pt/125% !important;
 }
 
 div.routersummary input[type=text] {
@@ -163,45 +171,49 @@ div.routersummary input[type=text] {
 }
 
 div.routersummary hr {
-     color: #eef;
-     background: #eef;
-     height: 2px;
-     border-bottom: 1px solid #eef;
-     margin: 8px 1px 7px 1px;
-     -moz-box-shadow: inset 0px 1px 1px 1px #99f;
+     color: #89f;
+     background: #89f;
+     height: 0px;
+     border-bottom: 1px solid #89f;
+     margin: 8px -1px 7px -1px;
 }
 
 div.routersummary h3 {
      border: 0px solid #f00;
      font-size: 9.5pt;
      letter-spacing: 0.05em;
-     margin: -7px 1px -7px 1px;
+     margin: -7px 0px -8px 0px;
      padding: 1px 0;
      background: #c5d5fb;
      text-transform: uppercase;
 }
 
 div.routersummary h4 {
-     border: 0px solid #f00;
+     border: 0;
      border-bottom: 0 !important;
      font-size: 8.5pt;
      letter-spacing: 0.05em;
-     margin: -7px 1px -7px 1px !important;
-     padding: 1px 3px;
+     margin: -7px 0px -8px 0px !important;
+     padding: 3px 0;
      background: #c1d1f7;
      text-transform: capitalize;
      text-decoration: none !important;
      color: #2b2;
+     line-height: 90%;
+}
+
+div.routersummary h3 a, div.routersummary h4 a {
+     text-decoration: none;
 }
 
 div.routersummary table {
      border: 0;
      text-align: center !important;
-     margin: -5px 4px -5px 3px;
-     width: 180px !important;
+     margin: -5px 0px -5px 0px;
+     width: 193px !important;
      overflow: hidden;
      font-size: 8pt;
-     padding: 0 -10px;
+     padding: 0 -12px;
      background-image: none !important;
      background-color: transparent !important;
 }
@@ -212,20 +224,47 @@ div.routersummary tr {
      border: 0 !important;
 }
 
+div.tunnels table {
+     margin: 0 -7px !important;
+     width: 193px;
+}
+
 div.tunnels table{
-     margin: 0 !important;
+     margin: -2px 0px -4px 0px !important;
+     text-align: center !important;
+     width: 190px;
 }
 
 .tunnels tr {
      padding: 2px 0 !important;
-     margin-left: -7px !important;
 }
+
+.tunnels a {
+     text-transform: capitalize;
+}
+
+.tunnels td:first-child {
+     width: 16px !important;
+     padding-right: 0px;
+     text-align: left;
+}
+
+.tunnels td:last-child {
+     width: 12px;
+     text-align: right;
+     margin-right: -2px;
+}    
      
 div.routersummary form {
      margin-top: -6px !important;
      margin-bottom: -4px !important;     
 }
 
+div.routersummary form:last-child {
+     padding-top: 3px !important;
+     margin-bottom: -10px !important;     
+}
+
 div.refresh {
      margin-top: 10px !important;
      margin-bottom: 10px !important;
@@ -251,21 +290,17 @@ div.routersummary td {
      border: 0 !important;
 }
 
-div.warning h3 {
-     border-bottom: 5px solid #fb7;
-     padding-bottom: 10px;
-}
-
 div.main {
-     margin: 0px 0px 0px 195px;
+     margin: 0px 1px 0px 200px;
      padding: 15px 15px 10px 15px;
      background: #eef;
-     border: 5px solid #bbf;
+     border: 1px solid #89f;
+     border-bottom: 1px solid #89f;
+     border-right: 1px solid #89f;
      border-top: 0;
      text-align: left;
      color: #001;
-     min-width: 570px;
-     -moz-box-shadow: inset 0px 0px 0px 1px #99f;
+     min-width: 500px;
 }
 
 div.main ul {
@@ -295,7 +330,7 @@ div.main textarea {
 
 div.main h2 {
      margin-top: 20px;
-     margin-bottom: -5px;
+     margin-bottom: 0px;
 }
 
 div.welcome {
@@ -325,17 +360,18 @@ div.wideload p !important {
 }
 
 div.news {
-     margin: -5px 0px 0 195px;
+     margin: -1px 1px 0 200px;
      padding: -10px 0px 8px 0px;
      background: #ffffc0;
-     border: 5px solid #bbf;
+     border: 1px solid #89f;
+     border-bottom: 1px solid #89f;
+     border-right: 1px solid #89f;
      text-align: right;
      color: #770;
-     min-width: 600px;
+     min-width: 500px;
      padding-bottom: 8px;
      padding-left: 10px;
      padding-right: 10px;
-     -moz-box-shadow: inset 0px 0px 0px 1px #99f;
      font-size: 7pt;
 }
 
@@ -387,16 +423,19 @@ div.news hr {
      color: #cc7;
      background: #cc7;
      height: 1px;
-     border: 0px solid #cccc77;
-     margin: 20px 0 2px 0;
+     border: 0px solid #cc7;
+     margin: 20px 0 0 0;
 }
 
 div.confignav {
-     padding: 12px 0 15px 0;
-     background: #cfc;
-     margin: -20px -20px 0 -20px;
-     border: 5px solid #bbf;
-     -moz-box-shadow: inset 0px 0px 0px 1px #99f;
+     padding: 10px 0 11px 0;
+     background: #ddf;
+     margin: -16px -16px 0 -16px;
+     border: 1px solid #89f;
+     font-size: 9.5pt;
+}
+
+div.confignav a {
 }
 
 div.configure {
@@ -411,7 +450,7 @@ div.configure hr {
 div.configure table {
      font-size: 9pt;
      font-weight: bold;
-     border: 1px solid #bbf;
+     border: 1px solid #89f;
 }
 
 div.configure tr, div.configure td {
@@ -419,7 +458,6 @@ div.configure tr, div.configure td {
 }
 
 div.configure tr {
-     -moz-box-shadow: inset 0px 0px 1px 0px #bbf;
 }
 
 div.configure li:first-child, div.main li:first-child {
@@ -442,14 +480,13 @@ div.configure h2:first-child {
 div.messages {
      padding: 0px 10px;
      background: #fff;
-     border: 5px solid #bbf;
+     border: 1px solid #89f;
      border-right: 0;
-     margin: -5px -15px 10px -20px;
+     margin: -1px -15px 10px -16px;
      text-align: center;
      font-size: 9pt;
      font-weight: bold;
      color: #474;
-     -moz-box-shadow: inset 0px 0px 0px 1px #99f;
 }
 
 div.messages li, div.messages ul {
@@ -469,32 +506,42 @@ h1 {
      font-size: 18pt;
      text-shadow: 0px 0px 1px rgba(0, 0, 32, 0.7);
      text-align: center;
-     border: 5px solid #bbf;
-     padding: 13px 10px 12px 10px;
-     margin: 0 0px 0 195px;
+     border: 1px solid #89f;
+     border-bottom: 1px solid #89f;
+     border-right: 1px solid #89f;
+     padding: 16px 10px 16px 10px;
+     margin: 0 1px 0 200px;
      line-height: 93%;
      text-transform: uppercase;
      letter-spacing: 0.3em;
      background: #fff;
-     min-width: 600px;
-     -moz-box-shadow: inset 0px 0px 0px 1px #99f;
+     min-width: 500px;
 }
 
 h2 {
      font-size: 14pt;
-     padding: 0px 10px 10px 10px;
-     border-bottom: 3px solid #aaf;
-     border-top: 0px solid #aaf;
+     padding: 10px;
+     border: 1px solid #89f;
      letter-spacing: 0.04em;
+     font-variant: small-caps; 
+     text-transform: capitalize; 
+     background: #fff;
+     text-shadow: 0px 0px 1px rgba(0, 0, 32, 0.7);
 }
 
 h3 {
      font-size: 12pt;
-     padding: 0 10px 10px 10px;
-     border-bottom: 3px solid #aaf;
-     border-top: 0px solid #aaf;
+     padding: 5px 10px;
+     border: 1px solid #89f;
      letter-spacing: 0.04em;
      margin-bottom: 10px;
+     background: #fff;
+}
+
+h2, h3 {
+     background-image: url("images/titlebg.png"); 
+     background-repeat: no-repeat; 
+     background-position: right center;
 }
 
 .proxyfooter{
@@ -504,7 +551,7 @@ h3 {
 
 table {
      border-collapse: collapse; 
-     border: 1px solid #bbf;
+     border: 1px solid #89f;
      margin: 0 0 5px 0;
      cell-padding: 1px;
      font-size: 7.5pt;
@@ -513,11 +560,11 @@ table {
 }
 
 table hr {
-     padding: 0px 0;
-     color: #bbf;
-     background: #bbf;
-     border: 0px solid #bbf;
-     margin: 0px -5px;
+     padding: 0;
+     color: #89f;
+     background: #89f;
+     border: 0px solid #89f;
+     margin: -5px -5px -10px -5px !important;
      height: 1px;
 }
 
@@ -525,11 +572,15 @@ table tt {
      font-size: 7.5pt;
 }
 
+table code {
+     font-size: 120%;
+}
+
 th {
      background-color: #fff;
      padding: 8px 2px;
      text-align: center;
-     border-bottom: 1px solid #bbf;
+     border-bottom: 1px solid #89f;
 }
 
 tt {
@@ -553,10 +604,10 @@ tr:nth-child(odd) {
 }
 
 hr {
-     color: #aaf;
-     background: #aaf;
-     height: 3px;
-     border: 0px solid #aaf;
+     color: #89f;
+     background: #89f;
+     height: 2px;
+     border: 0px solid #89f;
      margin: 3px 0;
 }
 
@@ -655,10 +706,10 @@ p {
 }
 
 .langbox {
-     margin: 10px -20px 0px 5px;
+     margin: 18px -20px 0px 5px;
      color: #001;
      font-size: 7pt;
-     width: 220px;
+     width: 280px;
      text-align: center;
      float: right;
      valign: middle;
@@ -695,6 +746,7 @@ a:hover{
      color: #f60;
      text-decoration: underline;
      font-weight: bold;
+     text-shadow: 0px 0px 1px rgba(255, 96, 0, 0.7);
 }
 
 a:active{
@@ -713,9 +765,9 @@ tt {
      font-weight: bold;
      color: darkgreen;
 }
-
+ 
 .tablefooter {
-     border: 1px solid #bbf;
+     border: 1px solid #a8f;
 }
 
 .tablefooter tr, .tablefooter td {
@@ -725,7 +777,7 @@ tt {
      line-height: 150%;
      word-wrap: nowrap;
      padding: 8px 1px;
-     border-top: 2px solid #bbf;
+     border-top: 2px solid #89f;
 }
 
 .tidylist {
@@ -735,14 +787,9 @@ tt {
 }
 
 div.graphspanel {
-     padding: 15px 5px 20px 5px;
-     margin: -20px;
-     background: #ddf url('images/lightbluetile.png');
-     -moz-border-radius: 4px;
-     -khtml-border-radius: 4px;
-     border-radius: 4px;
-     border: 5px solid #bbf;
-     -moz-box-shadow: inset 0px 0px 1px 0px #002;
+     padding: 10px 5px 20px 5px;
+     margin: -16px -16px -11px -16px;
+     border: 1px solid #89f;
      text-align: center !important;   
 }
 
@@ -756,7 +803,7 @@ div.graphspanel img {
 }
 
 div.graphspanel img:hover {
-     border: 1px solid #003;
+     border: 1px solid #89f;
      padding: 2px;
      margin: 6px;
      text-align: center !important;
@@ -777,4 +824,4 @@ div.graphspanel form:last-child {
 div.graphspanel h3 {
      text-align: left;
      margin: 10px 20px 10px 20px;
-}
+}
\ No newline at end of file
diff --git a/installer/resources/themes/console/classic/console_big.css b/installer/resources/themes/console/classic/console_big.css
index e1f56c69e6a9709f971c32bfb16b6ffdd4e39aeb..a5b221a9dedb974da2ce48e499c9b899755714fe 100644
--- a/installer/resources/themes/console/classic/console_big.css
+++ b/installer/resources/themes/console/classic/console_big.css
@@ -1,5 +1,5 @@
 /* I2P Theme: I2P Classic Theme Override */
-/* Description: Larger fontsize override for console to accomodate foreign charactersets */
+/* I2P Description: Larger fontsize override for console to accomodate foreign charactersets */
 /* Author: Dr|Z3d */
 
 
@@ -20,8 +20,6 @@ div.routersummary h4 {
 
 div.routersummary table {
      font-size: 9pt;
-     margin: -5px 0px -5px -1px;
-     width: 188px !important;
 }
 
 div.routersummary table a:link, div.routersummary table a:visited {
@@ -33,9 +31,6 @@ div.tunnels a {
 }
 
 div.tunnels table {
-     width: 186px !important;
-     text-align: center;
-     margin: -4px 1px !important;
 }
 
 div.tunnels td:first-child, div.tunnels td:last-child  {
diff --git a/installer/resources/themes/console/classic/images/titlebg.png b/installer/resources/themes/console/classic/images/titlebg.png
new file mode 100644
index 0000000000000000000000000000000000000000..b524e04e24a7085356d89ba7d3cdb685b2c93ec7
Binary files /dev/null and b/installer/resources/themes/console/classic/images/titlebg.png differ
diff --git a/installer/resources/themes/console/dark/console.css b/installer/resources/themes/console/dark/console.css
index 7f961ace359a3450b0f20379b4bd109fa71413c1..4fd5fa09e48ce522741a89930fce65748831226c 100644
--- a/installer/resources/themes/console/dark/console.css
+++ b/installer/resources/themes/console/dark/console.css
@@ -1,12 +1,13 @@
-/* Not yet complete. Subject to flux and change. dr|z3d - 07.25.09 */
+/* I2P Console theme: "Camo" by dr|z3d. Aka "dark". As in ops. */
 
 body {
      margin: 20px 5px 0 15px;
      padding: 0;
      text-align: center;
-     background: #002;
-     color: #FFF;
+     background: #010 url('images/camotile.png') center bottom;
+     color: #EE9;
      font: 9pt/130% "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
+     
 }
 
 .hide {
@@ -22,20 +23,20 @@ pre {
      overflow-x: scroll;
      text-align: left;
      font: 9pt "Lucida Console", "DejaVu Sans Mono", Courier, mono;
-     color: #fff;
+     color: #EE9;
 }
 
 div.logo {
      float: left;
      padding: 10px;
      text-align: center;
-     font-color: #fff;
+     font-color: #EE9;
      margin: 0 20px 0 20px;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
-     background: #003 url('images/darkbluebg.png');
+     background: #030 url('images/darkbluebg.png');
      width: 175px;
      -moz-box-shadow: inset 0px 0px 1px 0px #009;
      -khtml-box-shadow: inset 0px 0px 1px 0px #009;
@@ -46,8 +47,8 @@ div.toolbar {
      margin: 0;
      padding: 10px;
      font-weight: bold;
-     background: #eef;
-     border: 1px solid #002;
+     background: #000;
+     border: 1px solid #000;
      display: none;
 }
 
@@ -59,7 +60,7 @@ div.toolbar a:link {
      border-radius: 4px;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
-     color: #002;
+     color: #000;
 }
 
 div.toolbar a:visited {
@@ -68,7 +69,7 @@ div.toolbar a:visited {
 
 div.toolbar a:hover, button:hover{
      border: 1px solid #f60;
-     background: #003;
+     background: #030;
      color: #f60;
 }
 
@@ -91,19 +92,20 @@ div.routersummary {
      width: 175px;
      padding: 10px;
      text-align: center;
-     border: 1px solid #99f;
-     background: #003;
-     background: url(images/darkbluebg.png);
-     color: #eef;
+     border: 1px solid #494;
+     background: #000;
+     background: #000 url(images/camotile2.png);
+     color: #EE9;
      font-size: 8pt;
      clear: left;/* fixes a bug in Opera */
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
      float: left;
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;     
-     box-shadow: inset 0px 0px 1px 0px #eef;
+/*     -moz-box-shadow: inset 0px 0px 0px 0px #EE9;
+     -khtml-box-shadow: inset 0px 0px 1px 0px #EE9;     
+     box-shadow: inset 0px 0px 1px 0px #EE9;*/
+     -moz-box-shadow: 0 1px 5px #000;
 }
 
 div.routersummary input[type=text] {
@@ -114,27 +116,26 @@ div.routersummary input[type=text] {
 }
 
 div.routersummary hr {
-     color: #99f;
-     background: #99f;
+     color: #494;
+     background: #494;
      height: 2px;
-     border-bottom: 1px solid #99f;
+     border-bottom: 1px solid #494;
      margin: 8px -10px 7px -10px;
-     -moz-box-shadow: inset 0px 1px 1px 1px #001;
+     -moz-box-shadow: inset 0px 1px 1px 1px #000;
 }
 
 div.routersummary h3 {
      border: 0;
      font-size: 9.5pt;
      letter-spacing: 0.04em;
-     margin: -7px -9px -8px -9px;
+     margin: -7px -10px -8px -10px;
      padding: 2px 0 3px 0 !important;
-     background: #007;
      text-transform: uppercase;
      -moz-border-radius: 0;
      -khtml-border-radius: 0;
      border-radius: 0;
-     background: #007;
-     background-image: -moz-linear-gradient(top, bottom, from(#007), to(#005), color-stop(7%, #007), color-stop(100%, #005));
+     background: #000 url('images/header.png') center center ;
+     background-image: -moz-linear-gradient(top, bottom, from(#005), to(#030), color-stop(7%, #000), color-stop(100%, #005));
 }
 
 div.routersummary h4 {
@@ -144,19 +145,19 @@ div.routersummary h4 {
      letter-spacing: 0.02em;
      margin: -7px -9px -10px -9px !important;
      padding: 2px 3px 5px 3px;
-     background: #005;
+     background: #000;
      text-transform: capitalize;
      text-decoration: none !important;
      color: #2b2;
-     background-image: -moz-linear-gradient(top, bottom, from(#001), to(#005), color-stop(10%, #005), color-stop(100%, #004));
+     background-image: -moz-linear-gradient(top, bottom, from(#000), to(#005), color-stop(10%, #005), color-stop(100%, #004));
      line-height: 100%;
 }
 
 div.routersummary table {
      border: 0;
      text-align: center !important;
-     margin: -5px -4px -5px -5px !important;
-     width: 185px !important;
+     margin: -5px -7px -5px -7px !important;
+     width: 188px !important;
      overflow: hidden;
      font-size: 8pt;
      padding: 0 -10px;
@@ -189,7 +190,8 @@ div.refresh {
 }
 
 div.routersummary a:link, div.routersummary a:visited {
-     text-shadow: 0px 0px 1px rgba(192, 192, 255, 0.5);
+     text-shadow: 1px 1px 1px rgba(0, 16, 0, 0.8);
+     text-shadow: 0px 0px 2px #010 !important;
 }
 
 div.routersummary a:hover {
@@ -210,28 +212,39 @@ div routersummary hr:last-child {
 
 div.tunnels {
      padding-top: 3px !important;
-     margin-left: -2px;
+     margin-left: -4px;
      text-align: center;
 }
 
 div.tunnels table {
-     margin: -3px 0 !important;
+     margin: -5px 0 -5px -2px !important;
 }
 
 div.tunnels td {
-     padding: 1px 2px 1px 2px;
+     padding: 1px 0px 1px 0px;
 }
+
 div.tunnels td:first-child {
      width: 16px;
+     text-align: left;
+     padding-right: 2px;
+}
+
+div.tunnels td:last-child {
+     text-align: right;
+}
+
+div.tunnels tr {
+/*     border: 1px solid #494 !important;*/
 }
 
 div.warning {
      margin: 5px 20px 10px 240px;
      padding: 5px 25px 20px 75px;
      background: #005;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      text-align: left;
-     color: #fff;
+     color: #EE9;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
@@ -250,8 +263,8 @@ div.warning {
 div.sorry {
      margin: 15px 15px 10px 220px;
      padding: 20px 20px 20px 75px;
-     background: #005;
-     border: 1px solid #99f;
+     background: #020;
+     border: 1px solid #494;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
@@ -262,65 +275,74 @@ div.sorry {
      -moz-box-shadow: inset 0px 0px 0px 1px #d00;
      word-wrap: break-word;
      font-weight: bold;
-     color: #eef;
+     color: #EE9;
 }
 
 div.sorry hr {
-     color: #eef;
-     background: #eef;
+     color: #EE9;
+     background: #EE9;
      height: 1px;
-     border: 1px solid #eef;
+     border: 1px solid #EE9;
      margin: 10px 0;
 }     
 
 div.main {
-     margin: 0px 0px 20px 195px;
-     padding: 0 15px 15px 25px;
-     background: #002;
+     margin: 15px 15px 20px 220px;
+     padding: 0 15px 15px 15px;
      text-align: left;
-     color: #eef;
+     color: #EE9;
      width: auto;
 /*  overflow-x: scroll; */
+     border: 1px solid #494;
+     -moz-border-radius: 4px;
+     -khtml-border-radius: 4px;
+     border-radius: 4px;
+     background: #000;/* url(images/camotile2.png);*/
+     min-width: 620px;
+     -moz-box-shadow: 0 1px 5px #000;
 }
 
 div.main textarea {
-     background: #002;
-     color: #fff;
+     background: #000;
+     color: #EE9;
      font: 8pt "Lucida Console", "DejaVu Sans Mono", Courier, mono;
 }
 
 div.news {
      margin: 15px 15px 15px 220px;
      padding: 5px 30px 10px 30px;
-     border: 1px solid #99f;
-     background: #004;
-     background-image: -moz-linear-gradient(top, bottom, from(#003), to(#005), color-stop(30%, #003), color-stop(100%, #001));
-/*     background: #003 url("images/darkbluetile.png");*/
-     color: #aaf;
+     border: 1px solid #494;
+     background: #000;
+/*     background-image: -moz-linear-gradient(top, bottom, from(#030), to(#005), color-stop(30%, #030), color-stop(100%, #000));///*/
+     background: #000 url("images/bg2.png")no-repeat scroll bottom right;
+     color: #7b7;
      border-radius: 4px;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      font-size: 7.5pt;
      text-align: right;
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;
+/*     -moz-box-shadow: inset 0px 0px 0px 0px #EE9;
+     -khtml-box-shadow: inset 0px 0px 1px 0px #EE9;
+     box-shadow: inset 0px 0px 1px 0px #EE9;*/
+     -moz-box-shadow: 0 1px 5px #000;
+     min-width: 590px;
 }
 
 div.news li {
      text-align: justify;
      list-style: url('images/info_dark.png');
-     margin: 0 10px 0 20px;
+     list-style: none;
+     margin: 0 10px 0 0px;
      padding: 5px 5px 5px 0;
      vertical-align: middle;
      word-wrap: break-word;
-     color: #99f;
+     color: #494;
 }
 
 div.news h4 {
      border-bottom: 1px;
      border-bottom-style: dotted;
-     border-bottom-color: #99f;
+     border-bottom-color: #494;
      padding: 0 0 0px 0;
      margin: 5px 0 10px 0;
      font-size: 10pt;
@@ -337,7 +359,7 @@ div.news h4:first-child {
 div.news p {
      margin-top: -5px;
      font-size: 8.5pt;
-     color: #eef;
+     color: #EE9;
 }
 
 div.news hr {
@@ -347,31 +369,25 @@ div.news hr {
 div.confignav {
      padding: 15px 10px !important;
      margin: 15px 0;
-     background: #004 url('images/darkbluebg.png');
+     background: #000 url('images/header.png') center center repeat-x ;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      font-size: 9.5pt !important;
      font-weight: bold !important;
      line-height: 160% !important;
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;
+
 }
 
 div.configure {
-     padding: 5px 15px 0 15px;
+/*     padding: 5px 15px 0 15px;
      margin: 10px 0px;
-     background: #005;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
-     border: 1px solid #99f;
-     background: #003 url(images/darkbluebg.png);
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;     
+     border: 1px solid #494; */
+     background: #000;/* url(images/camotile2.png);*/
 }
 
 div.messages {
@@ -380,11 +396,8 @@ div.messages {
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
-     border: 1px solid #99f;
-     background: #008 url('images/lightbluetile.png');
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;
+     border: 1px solid #494;
+     background: #000;/* url('images/lightbluetile.png');*/
      font-weight: bold;
      font-size: 9pt;
      color: #ddf;
@@ -408,20 +421,20 @@ div.messages li {
 }
 
 div.graphspanel {
-     padding: 10px 15px 0 15px;
-     margin: 15px 0px;
-     background: #005;
+     padding: 0;
+     margin: 15px 0px -15px 0;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
-     border: 1px solid #99f;
-     background: #003 url(images/darkbluebg.png);
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;
+/*     border: 1px solid #494;*/
+     background: #000;/* url(images/camotile.png);*/
      text-align: center;
 }
 
+div.widepanel h3 {
+     text-align: left !important;
+}
+
 div.graphspanel form {
      text-align: left;
      padding: 0 15px 0px 15px;
@@ -432,23 +445,21 @@ div.graphspanel hr {
 }
 
 div.graphspanel img {
-     border: 1px solid #001;
+     border: 1px solid #494;
      padding: 3px;
      margin: 5px;
      text-align: center !important;
-     background: #002;
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;
+     background: #000;
+
      opacity: 0.8;
 }
 
 div.graphspanel img:hover {
-     border: 1px solid #001;
+     border: 1px solid #000;
      padding: 3px;
      margin: 5px;
      text-align: center !important;
-     background: #002;
+     background: #000;
      -moz-box-shadow: inset 0px 0px 1px 1px #f60;
      -khtml-box-shadow: inset 0px 0px 1px 1px #f60;
      box-shadow: inset 0px 0px 1px 1px #f60;
@@ -458,18 +469,18 @@ div.graphspanel img:hover {
 table {
      border-collapse: collapse;
      width: 100%;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      cell-padding: 1px;
      font-size: 7pt;
-     background: #003;
+     background: #030;
      margin: 1px 0;
 }
 
 table hr {
      padding: 0px 0;
-     color: #99f;
-     background: #99f;
-     border: 0px solid #99f;
+     color: #494;
+     background: #494;
+     border: 0px solid #494;
      margin: 0px 0px;
      height: 1px;
      display: none;
@@ -477,12 +488,13 @@ table hr {
 
 th {
      padding: 6px 2px;
-     color: #eef;
+     color: #EE9;
      text-align: center;
      font-size: 9pt;
-     background: #004 url('images/tabletitledark.png') repeat-x;
-     border-top: 1px solid #99f;
-     border-bottom: 1px solid #99f !important;     
+     background: #000; /*url('images/tabletitledark.png') repeat-x;*/
+     background: #000 url('images/header.png') center center repeat-x ;
+     border-top: 1px solid #494;
+     border-bottom: 1px solid #494 !important;     
      line-height: 110%;
 }
 
@@ -491,27 +503,27 @@ tr {
 }
 
 tr:nth-child(even) {
-     background: #002 url('images/darkerbluetile.png') !important;
+     background: #010;/* url('images/darkerbluetile.png') !important;*/
      vertical-align: middle;
 }
 
 tr:nth-child(odd) {
-     background: #003 url('images/darkbluetile.png') !important;
+     background: #000800;/* url('images/darkbluetile.png') !important;*/
      vertical-align: middle;
 }
 /*
 tr:last-child {
      background: #004 url('images/lightbluetile.png') !important;
      font-weight: bold;
-     border: 1px solid #99f !important;
+     border: 1px solid #494 !important;
 }
 */
 td {
-     padding: 6px 3px;
-     color: #eef;
+     padding: 4px 6px;
+     color: #EE9;
      vertical-align: middle;
-     border-top: 1px inset #006;
-     border-bottom: 1px outset #006;   
+     border-top: 1px inset #494;
+     border-bottom: 1px outset #494;   
 }
 
 td img {
@@ -529,7 +541,7 @@ div.main li {
      list-style: square;
      margin: 2px 0px 2px 30px;
      padding: 1px 20px 1px 0px;
-     line-height: 150%;
+/*     line-height: 150%;*/
      word-wrap: break-word;
 }
 
@@ -559,18 +571,19 @@ ul {
 
 code {
      text-align: left;
-     font: 8pt "Lucida Console", "DejaVu Sans Mono", Courier, mono;
+     font: 8.5pt "Lucida Console", "DejaVu Sans Mono", Courier, mono;
+     color: #dd0;
 }
 
 a:link, h2 a:link{
-     color: #99f;
+     color: #494;
      text-decoration: none;
      font-weight: bold;     
      word-wrap: break-word;
 }
 
 a:visited{
-     color: #77f;
+     color: #7b7;
      text-decoration: none;
      font-weight: bold;     
      word-wrap: break-word;
@@ -601,7 +614,7 @@ p {
 
 h1 {
      text-align: left;
-     color: #fff;
+     color: #EE9;
      padding: 10px 15px;
      margin: 0 15px 10px 220px;
      font-size: 16pt;
@@ -609,65 +622,68 @@ h1 {
      font-style: normal;
      text-transform: uppercase;
      letter-spacing: 0.15em;
-     text-shadow: 0px 0px 3px rgba(255, 255, 255, 0.8);
+     text-shadow: 0px 0px 2px #010;
      white-space: normal;
-     background: #002 //url('images/darkbluebg.png');
-     background-image: -moz-linear-gradient(top, bottom, from(#001), to(#003), color-stop(30%, #001), color-stop(100%, #001));
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;
-     border: 1px solid #99f;
+     background: #000 url("images/scope.png")no-repeat scroll right top;
+     background: #000 url("images/bg2.png")no-repeat scroll top right;
+     background: #000 url('images/header.png') center center ;
+     background-image: -moz-linear-gradient(top, bottom, from(#000), to(#030), color-stop(30%, #000), color-stop(100%, #000));
+     border: 1px solid #494;
      border-radius: 4px;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      line-height: 120%;
+     min-width: 620px;
+     -moz-box-shadow: 0 1px 5px #000;
 }
 
 h2 {
      font-size: 12pt;
-     color: #fff;
-     text-shadow: 0px 0px 1px rgba(255, 255, 255, 0.5);
+     color: #EE9;
+     text-shadow: 0px 0px 2px #010;
      letter-spacing: 0.05em;
-     background: #002; // url('images/darkbluebg.png');
-     background-image: -moz-linear-gradient(top, bottom, from(#001), to(#003), color-stop(30%, #001), color-stop(100%, #001));
+     background: #000 url(images/camotile2.png);
+     background-image: -moz-linear-gradient(top, bottom, from(#000), to(#030), color-stop(30%, #000), color-stop(100%, #000));
+     background: #000 url('images/header.png') center center ;
      padding: 5px 10px 8px 10px;
      wordwrap: none;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      border-radius: 4px;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      vertical-align: middle;
      margin: 15px 0 12px 0 !important;
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;
+    text-transform: uppercase;
      word-wrap: break-word;
 }
 
 h2 a:visited {
-     color: #44f;
+     color: #191;
 }
 
 h2 a:hover {
      color: #f60;
-     text-shadow: 0px 0px 1px rgba(255, 255, 72, 0.9);
+     text-shadow: 0px 0px 1px rgba(255, 64, 0, 0.7);
 }
 
 h3 {
-     border: 1px solid #99f;
-     border-left: 5px solid #99f;
-     padding: 3px 5px 3px 5px;
+     border: 1px solid #494;
+     border-left: 5px solid #494;
+     padding: 5px 6px;
      margin: 12px 0 10px 0;
      border-radius: 0 4px 4px 0;
      -moz-border-radius: 0 4px 4px 0;
      -khtml-border-radius: 0 4px 4px 0;
-     background: #002;
+     background: #000 url(images/camotile.png);
+     background: #000 url('images/header.png') center center ;
+     text-transform: uppercase;
+     text-shadow: 0px 0px 2px #010;
 }
 
 h4 {
      border-bottom: 1px;
      border-bottom-style: solid;
-     border-bottom-color: #99f;
+     border-bottom-color: #494;
      padding: 0 0 10px 0;
      margin: 5px 0 10px 0;
      font-size: 11pt;
@@ -675,9 +691,8 @@ h4 {
 
 button, button:visited {
      font: bold 9pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
-     border: 1px outset #77f;
+     border: 1px outset #191;
      padding: 1px 3px;
-     background: #bbf;
      text-decoration: none;
      border-radius: 4px;
      -moz-border-radius: 4px;
@@ -688,26 +703,26 @@ button, button:visited {
      text-align: center;
      vertical-align: middle;
      min-width: 76px;
-     -moz-box-shadow: inset 0px 1px 1px 0px #55f;
-     -khtml-box-shadow: inset 0px 1px 1px 0px #55f;
-     box-shadow: inset 0px 1px 1px 0px #55f;
-     background: #003;
-     color: #99f;
+     -moz-box-shadow: inset 0px 1px 1px 0px #494;
+     -khtml-box-shadow: inset 0px 1px 1px 0px #191;
+     box-shadow: inset 0px 1px 1px 0px #191;
+     background: #000;
+     color: #494;
 }
 
 button:hover {
      border: 1px solid #f60;
-     -moz-box-shadow: inset 0px 1px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 1px 1px 0px #eef;
-     box-shadow: inset 0px 1px 1px 0px #eef;
-     background: #001;
+     -moz-box-shadow: inset 0px 1px 1px 0px #EE9;
+     -khtml-box-shadow: inset 0px 1px 1px 0px #EE9;
+     box-shadow: inset 0px 1px 1px 0px #EE9;
+     background: #000;
      color: #f60;
 }     
           
 button:active {
      border: 1px inset #f60;
      background: #f60;
-     color: #fff;
+     color: #EE9;
      -moz-box-shadow: inset 0px 0px 0px 0px #f60;
      -khtml-box-shadow: inset 0px 0px 0px 0px #f60;
      box-shadow: inset 0px 0px 0px 0px #f60;
@@ -720,9 +735,9 @@ button:active {
 }
 
 .langbox {
-     margin: 2px 2px 2px 5px;
+     margin: 17px 2px 2px 5px;
      padding: 7px 10px 5px 10px;
-     color: #eef;
+     color: #EE9;
      font-size: 7pt;
      width: 220px;
      text-align: right;
@@ -730,11 +745,21 @@ button:active {
      vertical-align: middle;
 }
 
+.langbox img {
+     opacity: 0.7;
+     -moz-box-shadow: 0 0 1px #000;
+}
+
+.langbox img:hover {
+     opacity: 1;
+     -moz-box-shadow: 0 0 1px #f60;
+}
+
 hr {
-     color: #99f;
-     background: #99f;
+     color: #494;
+     background: #494;
      height: 1px;
-     border: 0px solid #99f;
+     border: 0px solid #494;
      margin: 10px 0;
 }
 
@@ -748,12 +773,12 @@ sidebarlogo {
 }
 
 input {
-     border: 1px outset #55f;
-     -moz-box-shadow: inset 0px 1px 1px 0px #55f;
-     -khtml-box-shadow: inset 0px 1px 1px 0px #55f;
-     box-shadow: inset 0px 1px 1px 0px #55f;
-     background: #003;
-     color: #99f;
+     border: 1px outset #5f5;
+     -moz-box-shadow: inset 0px 1px 1px 0px #373;
+     -khtml-box-shadow: inset 0px 1px 1px 0px #373;
+     box-shadow: inset 0px 1px 1px 0px #373;
+     background: #000;
+     color: #494;
      margin: 5px;
      font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
      padding: 1px 2px;
@@ -765,16 +790,16 @@ input {
 }
 
 input:hover {
-     background: #001;
+     background: #000;
      color: #f60;
      border: 1px solid #f60;
-     -moz-box-shadow: inset 0px 1px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 1px 1px 0px #eef;
-     box-shadow: inset 0px 1px 1px 0px #eef;
+     -moz-box-shadow: inset 0px 1px 1px 0px #9e9;
+     -khtml-box-shadow: inset 0px 1px 1px 0px #9e9;
+     box-shadow: inset 0px 1px 1px 0px #9e9;
 }
 
 input:active {
-     background: #002;
+     background: #000;
      color: #f30;
      border: 1px solid #f30;
 }
@@ -782,16 +807,16 @@ input:active {
 input:active {
      border: 1px inset #f60;
      background: #f60;
-     color: #fff;
+     color: #EE9;
 }
 
 input[type=text] {
-     background: #002;
-     color: #eef;
+     background: #000;
+     color: #EE9;
      margin: 5px 10px;
      padding: 4px 2px;
      font: bold 8pt "Lucida Sans Unicode", "Bitstream Vera Sans", Verdana, Tahoma, Helvetica, sans-serif;
-     border: 1px solid #bbf;
+     border: 1px solid #494 !important;
      text-decoration: none;
      border-radius: 4px;
      -moz-border-radius: 4px;
@@ -802,7 +827,7 @@ input[type=text] {
 }
 
 input[type=text]:active, input[type=text]:hover {
-     background: #001;
+     background: #000;
 }
 
 fieldset {
@@ -811,10 +836,10 @@ position: relative;
 }
 
 select {
-     background: #002;
-     color: #eef;
+     background: #000;
+     color: #EE9;
      margin: 5px 10px;
-     border: 1px solid #bbf;
+     border: 1px solid #494;
      border-radius: 4px;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
@@ -824,8 +849,8 @@ select {
 }
 
 textarea {
-     background: #001;
-     color: #eef;
+     background: #000;
+     color: #EE9;
      padding: 5px;
      margin: 10px;
      border-radius: 4px;
@@ -835,7 +860,7 @@ textarea {
      min-height: 100px;
      min-width: 97%;
      text-align: left;
-     border: 1px solid #99f;
+     border: 1px solid #494;
 }
 
 form {}
@@ -849,39 +874,37 @@ form {}
      border-radius: 4px;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
-     border: 1px solid #001;
+     border: 1px solid #000;
      display: none;
 }        
 
 .statusnotes {
      font-style: italic;
      font-size: 8pt;
-     color: #eef;
+     color: #EE9;
      text-align: center;
-     border: 1px solid #99f !important;
+     border: 1px solid #494 !important;
 /*     border-top: 0px !important;*/
      margin: -3px 0 5px 0; 
      padding: 7px;
-     background: #004;
-     -moz-box-shadow: inset 0px 0px 0px 1px #009;
-     -khtml-box-shadow: inset 0px 0px 0px 1px #009;
-     box-shadow: inset 0px 0px 0px 1px #009;
+     background: #010;
+     -moz-box-shadow: inset 0px 0px 0px 1px #090;
+     -khtml-box-shadow: inset 0px 0px 0px 1px #090;
+     box-shadow: inset 0px 0px 0px 1px #090;
+/*     background: #000 url('images/header.png') repeat-x center center !important;*/
 }
 
 div.joblog {
-     margin: 	15px 0 15px 0;
+/*     margin: 	15px 0 15px 0;
      padding: 5px 20px 10px 20px !important;
-     border: 1px solid #99f;
-     background-color: #004;
-     background: url("images/darkbluebg.png");
-     color: #dfd;
-     border-radius: 4px;
-     -moz-border-radius: 4px;
-     -khtml-border-radius: 4px;
+     border: 1px solid #494;
+     background-color: #000;
+     background: #000; url("images/camotile.png");*/
+/*     color: #dfd;*/
+     border-radius: 4px 4px 0 0;
+     -moz-border-radius: 4px 4px 0 0;
+     -khtml-border-radius: 4px 4px 0 0;
      text-align: justify !important;
-     -moz-box-shadow: inset 0px 0px 1px 0px #eef;
-     -khtml-box-shadow: inset 0px 0px 1px 0px #eef;
-     box-shadow: inset 0px 0px 1px 0px #eef;
      overflow-x: scroll; /* Opera fix */
  }
  
@@ -953,14 +976,14 @@ position: relative;
 }
 
 .cells {
-     border: 1px inset #005;
-     border-left: 1px outset #002;     
+     border: 1px inset #494;
+     border-left: 1px outset #494;     
 }
 
 .tablefooter tr, .tablefooter td {
-     background: #004 url('images/tabletitledark.png') repeat-x !important;
-     border-top: 1px solid #99f;
-     border-bottom: 1px solid #99f !important;     
+     background: #000 url('images/header.png') repeat-x center center !important;
+     border-top: 1px solid #494;
+     border-bottom: 1px solid #494 !important;     
      font-size: 7pt;
      line-height: 110%;
 }
diff --git a/installer/resources/themes/console/dark/default.css b/installer/resources/themes/console/dark/default.css
index dc9ceede8ec5a7a1571f28711869ad0d2c0fb4df..68de1b28e584122e9028dd1882058b6a75ebc852 100644
--- a/installer/resources/themes/console/dark/default.css
+++ b/installer/resources/themes/console/dark/default.css
@@ -1,9 +1,11 @@
+/* I2P Console theme: "Camo" by dr|z3d. Aka "dark". As in ops. */
+
 body {
      margin: 0px;
      padding: 0px;
      text-align: center;
      font-family: "Lucida Sans Unicode", Verdana, Helvetica, sans-serif;
-     background-color: #001;
+     background: #010 url('images/camotile.png') center bottom;
      color: #000000;
      font-size: 9pt;
 /* we've avoided Tantek Hacks so far,
@@ -39,14 +41,14 @@ h4 {
      font-size: 14px;
      font-weight: bold !important;
      text-align: center;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      margin: 5px 0 15px 0;
      padding: 5px 10px;
-     background: #004 url(images/tabletitledark.png) repeat-x;
+     background: #000 url('images/header.png') center center repeat-x ;
      text-transform: uppercase;
-     text-shadow: 0px 0px 2px rgba(255, 255, 255, 0.9);
+     text-shadow: 0px 0px 2px rgba(0, 0, 0, 0.9);
      letter-spacing: 0.08em;
-     -moz-box-shadow: inset 0px 0px 4px 0px #009;
+     -moz-box-shadow: inset 0px 0px 4px 0px #090;
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
@@ -73,7 +75,7 @@ button {
 }
 
 textarea {
-     border: 1px solid #9999ff;
+     border: 1px solid #494;
 }
 
 br {
@@ -121,21 +123,21 @@ hr {
      clear: both;
      height: 1px;
      margin: 3px 0px 3px 0px;
-     border-bottom: 1px solid #99f;
+     border-bottom: 1px solid #494;
 }
 
 .subdivider {
-     border-bottom: 1px solid #99f;
+     border-bottom: 1px solid #494;
      padding: 5px 0px 0px 0px;
 }
 
 .freetext {
      width: 150px;
      height : 22px; 
-     border: 1px solid #9999ff;
+     border: 1px solid #494;
      padding: 2px;
      margin: 4px 0 2px 4px;
-     background-color: #002;
+     background-color: #020;
      font: bold 9pt "Lucida Console", "DejaVu Sans Mono", Courier, mono;
 }
 
@@ -147,8 +149,8 @@ hr {
      max-height: 24px;
      font-size: 9pt;
      font-weight: bold;
-     background-color: #b4c8ff;
-     color: black;
+     background-color: #000;
+     color: #9f9 !important;
      border: 1px outset #ddddc0;
      text-align: center;
      white-space: nowrap;
@@ -159,18 +161,25 @@ hr {
      background: url(images/tabletitlelight.png) repeat: x;
      vertical-align: middle;
      text-decoration: none;
+     border: 1px outset #5f5;
+     -moz-box-shadow: inset 0px 1px 1px 0px #373;
+     -khtml-box-shadow: inset 0px 1px 1px 0px #373;
+     box-shadow: inset 0px 1px 1px 0px #373;
 }
 
 .control:link {
-     color: #001;
+     color: #9f9;
      text-decoration: none;
 }
 
 .control:hover {
-     border: 1px solid #eeeeff;
-     background-color: #003;
-     color: #ff6600 !important;
+     border: 1px solid #f60;
+     background-color: #000;
+     color: #f60 !important;
      text-decoration: none;
+     -moz-box-shadow: inset 0px 1px 1px 0px #fff;
+     -khtml-box-shadow: inset 0px 1px 1px 0px #fff;
+     box-shadow: inset 0px 1px 1px 0px #fff;
 }
 
 .control:active {
@@ -181,7 +190,7 @@ hr {
 }
 
 .control:visited {
-     color: #001;
+     color: #010;
      text-decoration: none;
 }
 
@@ -192,12 +201,12 @@ hr {
      text-align: left;
      font-size: 9pt;
      color: white;
-     background-color: #002;
-     background: url(images/darkbluebg.png);
+     background-color: #020;
+     background: #000; /*url(images/camotile2.png);*/
      -moz-border-radius: 4px;
      -khtml-border-radius: 4px;
      border-radius: 4px;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      padding: 10px 20px;
 }
 
@@ -235,15 +244,15 @@ hr {
 }
 
 #globalOperationsPanel {
-     background-color: #003;
-     border: 1px solid #99f;
-     background: url(images/darkbluebg.png);
-     -moz-box-shadow: inset 0px 0px 0px 1px #f00;
+     background-color: #030;
+     border: 1px solid #494;
+     -moz-box-shadow: inset 0px 0px 0px 1px #932;
      padding: 5px 20px 11px 10px !important;
+     background: #000; /*url(images/camotile2.png);*/
 }
 
 #globalOperationsPanel .control {
-     width: 100px;
+     width: 120px;
 }
 
 .header {
@@ -254,12 +263,12 @@ hr {
 }
 
 a:link{
-     color: #99f;
+     color: #494;
      text-decoration: none;
 }
 
 a:visited{
-     color: #7bb;
+     color: #7b7;
      text-decoration: none;
 }
 
@@ -274,12 +283,12 @@ a:active{
 }
 
 input {
-     background-color: #002;
+     background-color: #020;
      color: #eef;
      margin: 0 2px 0 2px;
      font-family: "Lucida Sans Unicode", Verdana, Tahoma, Helvetica, sans-serif;
      font-weight: bold;
-     border: 1px solid #99f;
+     border: 1px solid #494;
 /*
      padding: 0px 2px 1px 2px;
 */
@@ -292,17 +301,17 @@ input hover {
      margin: 0 2px 0 2px;
      font-family: "Lucida Sans Unicode", Verdana, Tahoma, Helvetica, sans-serif;
      font-weight: bold;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      padding: 2px;
      text-decoration: none;
 }
 
 select {
-     background-color: #001;
+     background-color: #020;
      color: #eef;
      margin: 6px 2px 0 2px;
      font-family: "Lucida Sans Unicode", Verdana, Tahoma, Helvetica, sans-serif;
-     border: 1px solid #99f;
+     border: 1px solid #494;
      padding: 2px 2px 2px 4px;
      max-height: 24px;
 }
diff --git a/installer/resources/themes/console/dark/i2ptunnel.css b/installer/resources/themes/console/dark/i2ptunnel.css
index cc2f5d97e2bfb26d3fa658030a47c8725fa26a15..d353723109e1737e3a5b2fe2b14804fe372bdcbb 100644
--- a/installer/resources/themes/console/dark/i2ptunnel.css
+++ b/installer/resources/themes/console/dark/i2ptunnel.css
@@ -1,5 +1,6 @@
-/* I2P Tunnel Edit Page
-*/
+/* I2P Console theme: "Camo" by dr|z3d. Aka "dark". As in ops. */
+/* I2P Tunnel Edit Page */
+
 #tunnelEditPage input {
      width: 458px;
 }
@@ -82,8 +83,9 @@
      height: 100px;
      padding: 4px;
      margin: 0 0 3px 0;
-     background-color: #000088;
-     color: #fff;
+     background-color: #040;
+/*     background: #000 url("images/helitile.png")no-repeat scroll right top;*/
+     color: #ee9;
      font-family: "Lucida Console", "Andale Mono", "Courier New", Courier, mono;
      border: 1px inset #002;
 }
diff --git a/installer/resources/themes/console/dark/images/bg2.png b/installer/resources/themes/console/dark/images/bg2.png
new file mode 100644
index 0000000000000000000000000000000000000000..9af9046d26f6b8e250e57e3f3cad5cc0e95e61de
Binary files /dev/null and b/installer/resources/themes/console/dark/images/bg2.png differ
diff --git a/installer/resources/themes/console/dark/images/camotile.png b/installer/resources/themes/console/dark/images/camotile.png
new file mode 100644
index 0000000000000000000000000000000000000000..2d7ae1be11e85c0b2bc4a0d78e261e2116bc98ff
Binary files /dev/null and b/installer/resources/themes/console/dark/images/camotile.png differ
diff --git a/installer/resources/themes/console/dark/images/camotile2.png b/installer/resources/themes/console/dark/images/camotile2.png
new file mode 100644
index 0000000000000000000000000000000000000000..6d1a9989bb7c88e21d98daf1a0446851b78ce843
Binary files /dev/null and b/installer/resources/themes/console/dark/images/camotile2.png differ
diff --git a/installer/resources/themes/console/dark/images/darkbluebg.png b/installer/resources/themes/console/dark/images/darkbluebg.png
deleted file mode 100644
index 32a0972b94e66a702def8f4a8a3c62cb3d5bd42b..0000000000000000000000000000000000000000
Binary files a/installer/resources/themes/console/dark/images/darkbluebg.png and /dev/null differ
diff --git a/installer/resources/themes/console/dark/images/darkbluetile.png b/installer/resources/themes/console/dark/images/darkbluetile.png
deleted file mode 100644
index 5f7d1a01ffdb0f1923f280ab2fcd04cb3e6159e4..0000000000000000000000000000000000000000
Binary files a/installer/resources/themes/console/dark/images/darkbluetile.png and /dev/null differ
diff --git a/installer/resources/themes/console/dark/images/darkerbluetile.png b/installer/resources/themes/console/dark/images/darkerbluetile.png
deleted file mode 100644
index 2e28effafc342c4f06f859247988538ed3ed5ecd..0000000000000000000000000000000000000000
Binary files a/installer/resources/themes/console/dark/images/darkerbluetile.png and /dev/null differ
diff --git a/installer/resources/themes/console/dark/images/h1bg.png b/installer/resources/themes/console/dark/images/h1bg.png
deleted file mode 100644
index dd2ce33886bd43f3efb27b64860edfb2a0e91da6..0000000000000000000000000000000000000000
Binary files a/installer/resources/themes/console/dark/images/h1bg.png and /dev/null differ
diff --git a/installer/resources/themes/console/dark/images/header.png b/installer/resources/themes/console/dark/images/header.png
new file mode 100644
index 0000000000000000000000000000000000000000..4a8e7a9ecf6fbc6213f757a844c98bf4b0995d8a
Binary files /dev/null and b/installer/resources/themes/console/dark/images/header.png differ
diff --git a/installer/resources/themes/console/dark/images/i2plogo.png b/installer/resources/themes/console/dark/images/i2plogo.png
index 52d1fd6c7d7e7f5ccd9c1cac26f5502a4549d007..fb343194eeb89ff2336175609a4209b9389fd668 100644
Binary files a/installer/resources/themes/console/dark/images/i2plogo.png and b/installer/resources/themes/console/dark/images/i2plogo.png differ
diff --git a/installer/resources/themes/console/dark/images/lightbluetile.png b/installer/resources/themes/console/dark/images/lightbluetile.png
deleted file mode 100644
index f31f7cd8ed420d91d8546bb59cd3f9cd643ac2d4..0000000000000000000000000000000000000000
Binary files a/installer/resources/themes/console/dark/images/lightbluetile.png and /dev/null differ
diff --git a/installer/resources/themes/console/dark/images/tabletitledark.png b/installer/resources/themes/console/dark/images/tabletitledark.png
deleted file mode 100644
index 2616ec7a68cdbd6679c11b118b19ace0ea7a9878..0000000000000000000000000000000000000000
Binary files a/installer/resources/themes/console/dark/images/tabletitledark.png and /dev/null differ
diff --git a/installer/resources/themes/console/dark/images/tabletitlelight.png b/installer/resources/themes/console/dark/images/tabletitlelight.png
deleted file mode 100644
index 9c9092e7372739d8bd1deeabd0c125a81dc29c6e..0000000000000000000000000000000000000000
Binary files a/installer/resources/themes/console/dark/images/tabletitlelight.png and /dev/null differ
diff --git a/installer/resources/themes/console/dark/images/tile.png b/installer/resources/themes/console/dark/images/tile.png
new file mode 100644
index 0000000000000000000000000000000000000000..c8f98b265782ca33085aac87ee93d1679e5812ad
Binary files /dev/null and b/installer/resources/themes/console/dark/images/tile.png differ
diff --git a/installer/resources/themes/console/dark/images/titletile.png b/installer/resources/themes/console/dark/images/titletile.png
deleted file mode 100644
index 945acc5b981b768b8a64a6a9f7a8c969c17733ba..0000000000000000000000000000000000000000
Binary files a/installer/resources/themes/console/dark/images/titletile.png and /dev/null differ
diff --git a/installer/resources/themes/console/light/console.css b/installer/resources/themes/console/light/console.css
index 00979a190dfcf58300d2f058c176627da62d0290..942a7a873800f5822a4d370ac1f3791d0216654c 100644
--- a/installer/resources/themes/console/light/console.css
+++ b/installer/resources/themes/console/light/console.css
@@ -1,4 +1,4 @@
-/* Not yet complete. Subject to flux and change. dr|z3d - 07.25.09 */
+/* I2P Console Theme "Corporat" by dr|z3d. Aka "light". As in beer.*/
 
 body {
      margin: 15px 0 0 10px;
@@ -714,11 +714,11 @@ button:active{
 }
 
 .langbox {
-     margin: 4px 2px 4px 5px;
+     margin: 4px 10px 4px 5px;
      padding: 5px 5px;
      color: #001;
      font-size: 7pt;
-     width: 220px;
+     width: 260px;
      text-align: right;
      float: right;
      valign: middle;
diff --git a/installer/resources/themes/console/midnight/console.css b/installer/resources/themes/console/midnight/console.css
index 69e63305794179f3eded69db789b17930ba18911..0c66d9589905b68fccc25942a1eab200f65bbea3 100644
--- a/installer/resources/themes/console/midnight/console.css
+++ b/installer/resources/themes/console/midnight/console.css
@@ -738,10 +738,10 @@ p {
 }
 
 .langbox {
-     margin: 17px -20px 0px 5px;
+     margin: 17px -30px 0px 5px;
      color: #eef;
      font-size: 7pt;
-     width: 220px;
+     width: 280px;
      text-align: center;
      float: right;
      valign: middle;
diff --git a/router/java/src/net/i2p/router/Router.java b/router/java/src/net/i2p/router/Router.java
index bfcbe83a6f4018d5690652838cca263615b03b8d..eede0c768db98e63cee52893f4541fc4cfe174fa 100644
--- a/router/java/src/net/i2p/router/Router.java
+++ b/router/java/src/net/i2p/router/Router.java
@@ -19,10 +19,12 @@ import java.util.GregorianCalendar;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
 import java.util.TimeZone;
 import java.util.TreeSet;
+import java.util.concurrent.ConcurrentHashMap;
 
 import net.i2p.CoreVersion;
 import net.i2p.crypto.DHSessionKeyBuilder;
@@ -57,7 +59,7 @@ import net.i2p.util.SimpleTimer;
 public class Router {
     private Log _log;
     private RouterContext _context;
-    private final Properties _config;
+    private final Map<String, String> _config;
     /** full path */
     private String _configFilename;
     private RouterInfo _routerInfo;
@@ -120,7 +122,7 @@ public class Router {
     public Router(String configFilename) { this(configFilename, null); }
     public Router(String configFilename, Properties envProps) {
         _gracefulExitCode = -1;
-        _config = new Properties();
+        _config = new ConcurrentHashMap();
 
         if (configFilename == null) {
             if (envProps != null) {
@@ -168,15 +170,9 @@ public class Router {
 
         readConfig();
 
-        if (envProps == null) {
-            envProps = _config;
-        } else {
-            for (Iterator iter = _config.keySet().iterator(); iter.hasNext(); ) {
-                String k = (String)iter.next();
-                String v = _config.getProperty(k);
-                envProps.setProperty(k, v);
-            }
-        }
+        if (envProps == null)
+            envProps = new Properties();
+        envProps.putAll(_config);
 
         // This doesn't work, guess it has to be in the static block above?
         // if (Boolean.valueOf(envProps.getProperty("router.disableIPv6")).booleanValue())
@@ -203,6 +199,15 @@ public class Router {
             System.exit(-1);
         }
 
+        if (_config.get("router.firstVersion") == null) {
+            // These may be useful someday. First added in 0.8.2
+            _config.put("router.firstVersion", RouterVersion.VERSION);
+            String now = Long.toString(System.currentTimeMillis());
+            _config.put("router.firstInstalled", now);
+            _config.put("router.updateLastInstalled", now);
+            saveConfig();
+        }
+
         // This is here so that we can get the directory location from the context
         // for the zip file and the base location to unzip to.
         // If it does an update, it never returns.
@@ -276,30 +281,20 @@ public class Router {
     public void setConfigFilename(String filename) { _configFilename = filename; }
     
     public String getConfigSetting(String name) { 
-        synchronized (_config) {
-            return _config.getProperty(name); 
-        }
+            return _config.get(name); 
     }
     public void setConfigSetting(String name, String value) { 
-        synchronized (_config) {
-            _config.setProperty(name, value); 
-        }
+            _config.put(name, value); 
     }
     public void removeConfigSetting(String name) { 
-        synchronized (_config) {
             _config.remove(name); 
-        }
     }
     public Set getConfigSettings() { 
-        synchronized (_config) {
             return new HashSet(_config.keySet()); 
-        }
     }
     public Properties getConfigMap() { 
         Properties rv = new Properties();
-        synchronized (_config) {
-            rv.putAll(_config); 
-        }
+        rv.putAll(_config); 
         return rv;
     }
     
@@ -368,14 +363,19 @@ public class Router {
         _context.jobQueue().addJob(new StartupJob(_context));
     }
     
-    public void readConfig() {
+    /**
+     * This updates the config with all settings found in the file.
+     * It does not clear the config first, so settings not found in
+     * the file will remain in the config.
+     *
+     * This is synchronized with saveConfig()
+     */
+    public synchronized void readConfig() {
         String f = getConfigFilename();
         Properties config = getConfig(_context, f);
-        for (Iterator iter = config.keySet().iterator(); iter.hasNext(); ) {
-            String name = (String)iter.next();
-            String val = config.getProperty(name);
-            setConfigSetting(name, val);
-        }
+        // to avoid compiler errror
+        Map foo = _config;
+        foo.putAll(config);
     }
     
     /** this does not use ctx.getConfigDir(), must provide a full path in filename */
@@ -979,7 +979,7 @@ public class Router {
      */
     public void shutdownGracefully(int exitCode) {
         _gracefulExitCode = exitCode;
-        _config.setProperty(PROP_SHUTDOWN_IN_PROGRESS, "true");
+        _config.put(PROP_SHUTDOWN_IN_PROGRESS, "true");
         synchronized (_gracefulShutdownDetector) {
             _gracefulShutdownDetector.notifyAll();
         }
@@ -1001,7 +1001,7 @@ public class Router {
      */
     public int scheduledGracefulExitCode() { return _gracefulExitCode; }
     public boolean gracefulShutdownInProgress() {
-        return (null != _config.getProperty(PROP_SHUTDOWN_IN_PROGRESS));
+        return (null != _config.get(PROP_SHUTDOWN_IN_PROGRESS));
     }
     /** How long until the graceful shutdown will kill us?  */
     public long getShutdownTimeRemaining() {
@@ -1024,7 +1024,7 @@ public class Router {
     private class GracefulShutdown implements Runnable {
         public void run() {
             while (true) {
-                boolean shutdown = (null != _config.getProperty(PROP_SHUTDOWN_IN_PROGRESS));
+                boolean shutdown = (null != _config.get(PROP_SHUTDOWN_IN_PROGRESS));
                 if (shutdown) {
                     if (_gracefulExitCode == EXIT_HARD || _gracefulExitCode == EXIT_HARD_RESTART ||
                         _context.tunnelManager().getParticipatingCount() <= 0) {
@@ -1068,26 +1068,24 @@ public class Router {
      * this does escape the \r or \n that are unescaped in DataHelper.loadProps().
      * Note that the escaping of \r or \n was probably a mistake and should be taken out.
      *
-     * FIXME Synchronize!!
+     * Synchronized with file read in getConfig()
      */
-    public boolean saveConfig() {
+    public synchronized boolean saveConfig() {
         FileOutputStream fos = null;
         try {
             fos = new SecureFileOutputStream(_configFilename);
             StringBuilder buf = new StringBuilder(8*1024);
             buf.append("# NOTE: This I2P config file must use UTF-8 encoding\n");
-            synchronized (_config) {
-                TreeSet ordered = new TreeSet(_config.keySet());
-                for (Iterator iter = ordered.iterator() ; iter.hasNext(); ) {
-                    String key = (String)iter.next();
-                    String val = _config.getProperty(key);
+            TreeSet ordered = new TreeSet(_config.keySet());
+            for (Iterator iter = ordered.iterator() ; iter.hasNext(); ) {
+                String key = (String)iter.next();
+                String val = _config.get(key);
                     // Escape line breaks before saving.
                     // Remember: "\" needs escaping both for regex and string.
                     // NOOO - see comments in DataHelper
                     //val = val.replaceAll("\\r","\\\\r");
                     //val = val.replaceAll("\\n","\\\\n");
-                    buf.append(key).append('=').append(val).append('\n');
-                }
+                buf.append(key).append('=').append(val).append('\n');
             }
             fos.write(buf.toString().getBytes("UTF-8"));
         } catch (IOException ioe) {
@@ -1183,6 +1181,9 @@ public class Router {
                 }
             }
             if (ok) {
+                // This may be useful someday. First added in 0.8.2
+                _config.put("router.updateLastInstalled", "" + System.currentTimeMillis());
+                saveConfig();
                 boolean deleted = updateFile.delete();
                 if (!deleted) {
                     System.out.println("ERROR: Unable to delete the update file!");
diff --git a/router/java/src/net/i2p/router/RouterVersion.java b/router/java/src/net/i2p/router/RouterVersion.java
index f6e6df3a5c0d10fbf1efc2f7069c342c2fe16f4e..c10128fe6223a59f4fa2320e38c3309487438a87 100644
--- a/router/java/src/net/i2p/router/RouterVersion.java
+++ b/router/java/src/net/i2p/router/RouterVersion.java
@@ -18,7 +18,7 @@ public class RouterVersion {
     /** deprecated */
     public final static String ID = "Monotone";
     public final static String VERSION = CoreVersion.VERSION;
-    public final static long BUILD = 4;
+    public final static long BUILD = 6;
 
     /** for example "-test" */
     public final static String EXTRA = "";
diff --git a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java
index 4041f3dadbe3830ed096c913e02ca6a9d56b9a0d..b161909c8aa457f2a9f50593d467e91aefba891c 100644
--- a/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java
+++ b/router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java
@@ -33,21 +33,24 @@ import net.i2p.util.Log;
  *
  * The NTCP transport sends individual I2NP messages AES/256/CBC encrypted with
  * a simple checksum.  The unencrypted message is encoded as follows:
+ *<pre>
  *  +-------+-------+--//--+---//----+-------+-------+-------+-------+
  *  | sizeof(data)  | data | padding | adler checksum of sz+data+pad |
  *  +-------+-------+--//--+---//----+-------+-------+-------+-------+
+ *</pre>
  * That message is then encrypted with the DH/2048 negotiated session key
  * (station to station authenticated per the EstablishState class) using the
  * last 16 bytes of the previous encrypted message as the IV.
  *
  * One special case is a metadata message where the sizeof(data) is 0.  In
  * that case, the unencrypted message is encoded as:
+ *<pre>
  *  +-------+-------+-------+-------+-------+-------+-------+-------+
  *  |       0       |      timestamp in seconds     | uninterpreted             
  *  +-------+-------+-------+-------+-------+-------+-------+-------+
  *          uninterpreted           | adler checksum of sz+data+pad |
  *  +-------+-------+-------+-------+-------+-------+-------+-------+
- * 
+ *</pre>
  *
  */
 public class NTCPConnection implements FIFOBandwidthLimiter.CompleteListener {