diff --git a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java
index c963ecce5456118324ae33cc5a249051da5397fd..44bbbe7813cd035e4887e6760e7bde0c9c1b6a7c 100644
--- a/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java
+++ b/apps/addressbook/java/src/net/i2p/addressbook/ConfigParser.java
@@ -35,6 +35,7 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 
+import net.i2p.util.SecureFile;
 import net.i2p.util.SecureFileOutputStream;
 
 /**
@@ -280,7 +281,7 @@ public class ConfigParser {
      *             if file cannot be written to.
      */
     public static void write(Map map, File file) throws IOException {
-        File tmp = File.createTempFile("hoststxt-", ".tmp", file.getAbsoluteFile().getParentFile());
+        File tmp = SecureFile.createTempFile("hoststxt-", ".tmp", file.getAbsoluteFile().getParentFile());
         ConfigParser
                 .write(map, new BufferedWriter(new OutputStreamWriter(new SecureFileOutputStream(tmp), "UTF-8")));
         boolean success = tmp.renameTo(file);
diff --git a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
index 8edc92fdf37b367e3652566288c7ef2bacfdc588..001928d4797438615fd61f7e8fafe8e4a9705179 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/I2PSnarkUtil.java
@@ -27,6 +27,7 @@ import net.i2p.util.EepGet;
 import net.i2p.util.FileUtil;
 import net.i2p.util.Log;
 import net.i2p.util.SecureDirectory;
+import net.i2p.util.SecureFile;
 import net.i2p.util.SimpleScheduler;
 import net.i2p.util.SimpleTimer;
 import net.i2p.util.Translate;
@@ -244,7 +245,7 @@ public class I2PSnarkUtil {
         File out = null;
         try {
             // we could use the system tmp dir but deleteOnExit() doesn't seem to work on all platforms...
-            out = File.createTempFile("i2psnark", null, _tmpDir);
+            out = SecureFile.createTempFile("i2psnark", null, _tmpDir);
         } catch (IOException ioe) {
             ioe.printStackTrace();
             if (out != null)
diff --git a/apps/i2psnark/java/src/org/klomp/snark/Storage.java b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
index 3e2a4ad6312771c115b70f98c062e20dac0633dd..87aa0d35723d4acc371b3d5ff8ee9a3fdc8d71ee 100644
--- a/apps/i2psnark/java/src/org/klomp/snark/Storage.java
+++ b/apps/i2psnark/java/src/org/klomp/snark/Storage.java
@@ -29,6 +29,7 @@ import java.util.List;
 import java.util.StringTokenizer;
 
 import net.i2p.crypto.SHA1;
+import net.i2p.util.SecureFile;
 
 /**
  * Maintains pieces on disk. Can be used to store and retrieve pieces.
@@ -462,7 +463,7 @@ public class Storage
   /** use a saved bitfield and timestamp from a config file */
   public void check(String rootDir, long savedTime, BitField savedBitField) throws IOException
   {
-    File base = new File(rootDir, filterName(metainfo.getName()));
+    File base = new SecureFile(rootDir, filterName(metainfo.getName()));
     boolean useSavedBitField = savedTime > 0 && savedBitField != null;
 
     List files = metainfo.getFiles();
@@ -623,7 +624,7 @@ public class Storage
         else
           {
             // The final element (file) in the hierarchy.
-            f = new File(base, name);
+            f = new SecureFile(base, name);
             if (!f.createNewFile() && !f.exists())
               throw new IOException("Could not create file " + f);
           }
diff --git a/core/java/src/net/i2p/I2PAppContext.java b/core/java/src/net/i2p/I2PAppContext.java
index 98e7d6af9aeb81b2d9435ce6151c80ab8e936150..b497796408cb2b6051d9386c3ed7dd230bf82c31 100644
--- a/core/java/src/net/i2p/I2PAppContext.java
+++ b/core/java/src/net/i2p/I2PAppContext.java
@@ -114,6 +114,11 @@ public class I2PAppContext {
      *
      */
     public static I2PAppContext getGlobalContext() { 
+        // skip the global lock
+        I2PAppContext rv = _globalAppContext;
+        if (rv != null)
+            return rv;
+
         synchronized (I2PAppContext.class) {
             if (_globalAppContext == null) {
                 _globalAppContext = new I2PAppContext(false, null);
@@ -122,6 +127,18 @@ public class I2PAppContext {
         return _globalAppContext; 
     }
     
+    /**
+     * Pull the default context, WITHOUT creating a new one.
+     * Use this in static methods used early in router initialization,
+     * where creating a context messes things up.
+     *
+     * @return context or null
+     * @since 0.8.2
+     */
+    public static I2PAppContext getCurrentContext() { 
+        return _globalAppContext; 
+    }
+    
     /**
      * Lets root a brand new context
      *
@@ -257,6 +274,7 @@ public class I2PAppContext {
             _appDir = _routerDir;
         }
         /******
+        (new Exception("Initialized by")).printStackTrace();
         System.err.println("Base directory:   " + _baseDir.getAbsolutePath());
         System.err.println("Config directory: " + _configDir.getAbsolutePath());
         System.err.println("Router directory: " + _routerDir.getAbsolutePath());
diff --git a/core/java/src/net/i2p/util/SecureDirectory.java b/core/java/src/net/i2p/util/SecureDirectory.java
index 30d609e96fb70d50c1c206e8005ff0024623d92a..d238cc694d18cad02704950afabe0ba60117c500 100644
--- a/core/java/src/net/i2p/util/SecureDirectory.java
+++ b/core/java/src/net/i2p/util/SecureDirectory.java
@@ -5,15 +5,14 @@ import java.io.File;
 /**
  * Same as File but sets the file mode after mkdir() so it can
  * be read and written by the owner only (i.e. 700 on linux)
+ * As of 0.8.2, just use SecureFile instead of this.
  *
  * @since 0.8.1
  * @author zzz
  */
 public class SecureDirectory extends File {
 
-    private static final boolean canSetPerms =
-        (new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0;
-    private static final boolean isNotWindows = !System.getProperty("os.name").startsWith("Win");
+    protected static final boolean isNotWindows = !System.getProperty("os.name").startsWith("Win");
 
     public SecureDirectory(String pathname) {
         super(pathname);
@@ -54,8 +53,8 @@ public class SecureDirectory extends File {
      *  Tries to set the permissions to 700,
      *  ignores errors
      */
-    private void setPerms() {
-        if (!canSetPerms)
+    protected void setPerms() {
+        if (!SecureFileOutputStream.canSetPerms())
             return;
         try {
             setReadable(false, false);
diff --git a/core/java/src/net/i2p/util/SecureFile.java b/core/java/src/net/i2p/util/SecureFile.java
new file mode 100644
index 0000000000000000000000000000000000000000..a931abb556adb5d3500abd91e4cc3f9d8593814e
--- /dev/null
+++ b/core/java/src/net/i2p/util/SecureFile.java
@@ -0,0 +1,81 @@
+package net.i2p.util;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Same as SecureDirectory but sets the file mode after createNewFile()
+ * and createTempFile() also. So just use this instead.
+ * Probably should have just made this class in the beginning and not had two.
+ *
+ * @since 0.8.2
+ * @author zzz
+ */
+public class SecureFile extends SecureDirectory {
+
+    public SecureFile(String pathname) {
+        super(pathname);
+    }
+
+    public SecureFile(String parent, String child) {
+        super(parent, child);
+    }
+
+    public SecureFile(File parent, String child) {
+        super(parent, child);
+    }
+
+    /**
+     *  Sets file to mode 600 if the file is created
+     */
+    @Override
+    public boolean createNewFile() throws IOException {
+        boolean rv = super.createNewFile();
+        if (rv)
+            setPerms();
+        return rv;
+    }
+
+    /**
+     *  Sets file to mode 600 when the file is created
+     */
+    public static File createTempFile(String prefix, String suffix) throws IOException {
+        File rv = File.createTempFile(prefix, suffix);
+        // same thing as below but static
+        SecureFileOutputStream.setPerms(rv);
+        return rv;
+    }
+
+    /**
+     *  Sets file to mode 600 when the file is created
+     */
+    public static File createTempFile(String prefix, String suffix, File directory) throws IOException {
+        File rv = File.createTempFile(prefix, suffix, directory);
+        // same thing as below but static
+        SecureFileOutputStream.setPerms(rv);
+        return rv;
+    }
+
+    /**
+     *  Tries to set the permissions to 600,
+     *  ignores errors
+     */
+    @Override
+    protected void setPerms() {
+        if (!SecureFileOutputStream.canSetPerms())
+            return;
+        try {
+            setReadable(false, false);
+            setReadable(true, true);
+            setWritable(false, false);
+            setWritable(true, true);
+            if (isNotWindows && isDirectory()) {
+                setExecutable(false, false);
+                setExecutable(true, true);
+            }
+        } catch (Throwable t) {
+            // NoSuchMethodException or NoSuchMethodError if we somehow got the
+            // version detection wrong or the JVM doesn't support it
+        }
+    }
+}
diff --git a/core/java/src/net/i2p/util/SecureFileOutputStream.java b/core/java/src/net/i2p/util/SecureFileOutputStream.java
index 01c6eba718976d2806cb04f8890b0c93ee53b7bd..9494827eb6fd8a718a2c5096b55b10ed1c157219 100644
--- a/core/java/src/net/i2p/util/SecureFileOutputStream.java
+++ b/core/java/src/net/i2p/util/SecureFileOutputStream.java
@@ -4,6 +4,8 @@ import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 
+import net.i2p.I2PAppContext;
+
 /**
  * Same as FileOutputStream but sets the file mode so it can only
  * be read and written by the owner only (i.e. 600 on linux)
@@ -13,7 +15,7 @@ import java.io.FileOutputStream;
  */
 public class SecureFileOutputStream extends FileOutputStream {
 
-    private static final boolean canSetPerms =
+    private static final boolean oneDotSix =
         (new VersionComparator()).compare(System.getProperty("java.version"), "1.6") >= 0;
 
     /**
@@ -51,12 +53,22 @@ public class SecureFileOutputStream extends FileOutputStream {
             setPerms(file);
     }
 
+    /** @since 0.8.2 */
+    static boolean canSetPerms() {
+        if (!oneDotSix)
+            return false;
+        I2PAppContext ctx = I2PAppContext.getCurrentContext();
+        if (ctx == null)
+            return true;
+        return !ctx.getBooleanProperty("i2p.insecureFiles");
+    }
+
     /**
      *  Tries to set the permissions to 600,
      *  ignores errors
      */
     public static void setPerms(File f) {
-        if (!canSetPerms)
+        if (!canSetPerms())
             return;
         try {
             f.setReadable(false, false);