diff --git a/bin/templates/project/Activity.java b/bin/templates/project/Activity.java
index d37247be..4f87f9fd 100644
--- a/bin/templates/project/Activity.java
+++ b/bin/templates/project/Activity.java
@@ -19,7 +19,6 @@
 
 package __ID__;
 
-import android.app.Activity;
 import android.os.Bundle;
 import org.apache.cordova.*;
 
@@ -29,6 +28,7 @@ public class __ACTIVITY__ extends DroidGap
     public void onCreate(Bundle savedInstanceState)
     {
         super.onCreate(savedInstanceState);
+        Config.init(this);
         super.loadUrl("file:///android_asset/www/index.html");
     }
 }
diff --git a/framework/src/org/apache/cordova/Config.java b/framework/src/org/apache/cordova/Config.java
new file mode 100644
index 00000000..1713d448
--- /dev/null
+++ b/framework/src/org/apache/cordova/Config.java
@@ -0,0 +1,196 @@
+/*
+       Licensed to the Apache Software Foundation (ASF) under one
+       or more contributor license agreements.  See the NOTICE file
+       distributed with this work for additional information
+       regarding copyright ownership.  The ASF licenses this file
+       to you under the Apache License, Version 2.0 (the
+       "License"); you may not use this file except in compliance
+       with the License.  You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+       Unless required by applicable law or agreed to in writing,
+       software distributed under the License is distributed on an
+       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+       KIND, either express or implied.  See the License for the
+       specific language governing permissions and limitations
+       under the License.
+*/
+
+package org.apache.cordova;
+
+import java.io.IOException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.cordova.api.LOG;
+
+import org.xmlpull.v1.XmlPullParserException;
+
+import android.app.Activity;
+
+import android.content.res.XmlResourceParser;
+
+import android.util.Log;
+
+public class Config {
+
+    public static final String TAG = "Config";
+
+    private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
+    private HashMap<String, Boolean> whiteListCache = new HashMap<String, Boolean>();
+
+    private static Config self = null;
+
+    public static void init(Activity action) {
+        if (self == null) {
+            self = new Config(action);
+        }
+    }
+
+    // Intended to be used for testing only; creates an empty configuration.
+    public static void init() {
+        if (self == null) {
+            self = new Config();
+        }
+    }
+
+    // Intended to be used for testing only; creates an empty configuration.
+    private Config() {
+    }
+
+    private Config(Activity action) {
+        if (action == null) {
+            LOG.i("CordovaLog", "There is no activity. Is this on the lock screen?");
+            return;
+        }
+
+        int id = action.getResources().getIdentifier("config", "xml", action.getPackageName());
+        if (id == 0) {
+            id = action.getResources().getIdentifier("cordova", "xml", action.getPackageName());
+            LOG.i("CordovaLog", "config.xml missing, reverting to cordova.xml");
+        }
+        if (id == 0) {
+            LOG.i("CordovaLog", "cordova.xml missing. Ignoring...");
+            return;
+        }
+
+        XmlResourceParser xml = action.getResources().getXml(id);
+        int eventType = -1;
+        while (eventType != XmlResourceParser.END_DOCUMENT) {
+            if (eventType == XmlResourceParser.START_TAG) {
+                String strNode = xml.getName();
+
+                if (strNode.equals("access")) {
+                    String origin = xml.getAttributeValue(null, "origin");
+                    String subdomains = xml.getAttributeValue(null, "subdomains");
+                    if (origin != null) {
+                        addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
+                    }
+                }
+                else if (strNode.equals("log")) {
+                    String level = xml.getAttributeValue(null, "level");
+                    LOG.i("CordovaLog", "Found log level %s", level);
+                    if (level != null) {
+                        LOG.setLogLevel(level);
+                    }
+                }
+                else if (strNode.equals("preference")) {
+                    String name = xml.getAttributeValue(null, "name");
+                    String value = xml.getAttributeValue(null, "value");
+
+                    LOG.i("CordovaLog", "Found preference for %s=%s", name, value);
+                    Log.d("CordovaLog", "Found preference for " + name + "=" + value);
+
+                    action.getIntent().putExtra(name, value);
+                }
+            }
+
+            try {
+                eventType = xml.next();
+            } catch (XmlPullParserException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Add entry to approved list of URLs (whitelist)
+     *
+     * @param origin        URL regular expression to allow
+     * @param subdomains    T=include all subdomains under origin
+     */
+    public static void addWhiteListEntry(String origin, boolean subdomains) {
+        if (self == null) {
+            return;
+        }
+
+        try {
+            // Unlimited access to network resources
+            if (origin.compareTo("*") == 0) {
+                LOG.d(TAG, "Unlimited access to network resources");
+                self.whiteList.add(Pattern.compile(".*"));
+            } else { // specific access
+                // check if subdomains should be included
+                // TODO: we should not add more domains if * has already been added
+                if (subdomains) {
+                    // XXX making it stupid friendly for people who forget to include protocol/SSL
+                    if (origin.startsWith("http")) {
+                        self.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://(.*\\.)?")));
+                    } else {
+                        self.whiteList.add(Pattern.compile("^https?://(.*\\.)?" + origin));
+                    }
+                    LOG.d(TAG, "Origin to allow with subdomains: %s", origin);
+                } else {
+                    // XXX making it stupid friendly for people who forget to include protocol/SSL
+                    if (origin.startsWith("http")) {
+                        self.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://")));
+                    } else {
+                        self.whiteList.add(Pattern.compile("^https?://" + origin));
+                    }
+                    LOG.d(TAG, "Origin to allow: %s", origin);
+                }
+            }
+        } catch (Exception e) {
+            LOG.d(TAG, "Failed to add origin %s", origin);
+        }
+    }
+
+    /**
+     * Determine if URL is in approved list of URLs to load.
+     *
+     * @param url
+     * @return
+     */
+    public static boolean isUrlWhiteListed(String url) {
+        if (self == null) {
+            return false;
+        }
+
+        // Check to see if we have matched url previously
+        if (self.whiteListCache.get(url) != null) {
+            return true;
+        }
+
+        // Look for match in white list
+        Iterator<Pattern> pit = self.whiteList.iterator();
+        while (pit.hasNext()) {
+            Pattern p = pit.next();
+            Matcher m = p.matcher(url);
+
+            // If match found, then cache it to speed up subsequent comparisons
+            if (m.find()) {
+                self.whiteListCache.put(url, true);
+                return true;
+            }
+        }
+        return false;
+    }
+}
diff --git a/framework/src/org/apache/cordova/CordovaChromeClient.java b/framework/src/org/apache/cordova/CordovaChromeClient.java
index be7c0c19..9f6ffd9c 100755
--- a/framework/src/org/apache/cordova/CordovaChromeClient.java
+++ b/framework/src/org/apache/cordova/CordovaChromeClient.java
@@ -197,7 +197,7 @@ public class CordovaChromeClient extends WebChromeClient {
         // Security check to make sure any requests are coming from the page initially
         // loaded in webview and not another loaded in an iframe.
         boolean reqOk = false;
-        if (url.startsWith("file://") || url.indexOf(this.appView.baseUrl) == 0 || this.appView.isUrlWhiteListed(url)) {
+        if (url.startsWith("file://") || url.indexOf(this.appView.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
             reqOk = true;
         }
 
diff --git a/framework/src/org/apache/cordova/CordovaWebView.java b/framework/src/org/apache/cordova/CordovaWebView.java
index 336cf521..547a450d 100755
--- a/framework/src/org/apache/cordova/CordovaWebView.java
+++ b/framework/src/org/apache/cordova/CordovaWebView.java
@@ -19,31 +19,25 @@
 
 package org.apache.cordova;
 
-import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Stack;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
+import org.apache.cordova.Config;
 import org.apache.cordova.api.CordovaInterface;
 import org.apache.cordova.api.CordovaPlugin;
 import org.apache.cordova.api.LOG;
 import org.apache.cordova.api.PluginManager;
 import org.apache.cordova.api.PluginResult;
-import org.xmlpull.v1.XmlPullParserException;
 
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
-import android.app.Activity;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.res.XmlResourceParser;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -66,15 +60,12 @@ public class CordovaWebView extends WebView {
 
     public static final String TAG = "CordovaWebView";
 
-    /** The whitelist **/
-    private ArrayList<Pattern> whiteList = new ArrayList<Pattern>();
-    private HashMap<String, Boolean> whiteListCache = new HashMap<String, Boolean>();
     private ArrayList<Integer> keyDownCodes = new ArrayList<Integer>();
     private ArrayList<Integer> keyUpCodes = new ArrayList<Integer>();
 
     public PluginManager pluginManager;
     private boolean paused;
-    
+
     private BroadcastReceiver receiver;
 
 
@@ -343,72 +334,6 @@ public class CordovaWebView extends WebView {
         super.setWebChromeClient(client);
     }
 
-    /**
-     * Add entry to approved list of URLs (whitelist)
-     *
-     * @param origin        URL regular expression to allow
-     * @param subdomains    T=include all subdomains under origin
-     */
-    public void addWhiteListEntry(String origin, boolean subdomains) {
-        try {
-            // Unlimited access to network resources
-            if (origin.compareTo("*") == 0) {
-                LOG.d(TAG, "Unlimited access to network resources");
-                this.whiteList.add(Pattern.compile(".*"));
-            } else { // specific access
-                // check if subdomains should be included
-                // TODO: we should not add more domains if * has already been added
-                if (subdomains) {
-                    // XXX making it stupid friendly for people who forget to include protocol/SSL
-                    if (origin.startsWith("http")) {
-                        this.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://(.*\\.)?")));
-                    } else {
-                        this.whiteList.add(Pattern.compile("^https?://(.*\\.)?" + origin));
-                    }
-                    LOG.d(TAG, "Origin to allow with subdomains: %s", origin);
-                } else {
-                    // XXX making it stupid friendly for people who forget to include protocol/SSL
-                    if (origin.startsWith("http")) {
-                        this.whiteList.add(Pattern.compile(origin.replaceFirst("https?://", "^https?://")));
-                    } else {
-                        this.whiteList.add(Pattern.compile("^https?://" + origin));
-                    }
-                    LOG.d(TAG, "Origin to allow: %s", origin);
-                }
-            }
-        } catch (Exception e) {
-            LOG.d(TAG, "Failed to add origin %s", origin);
-        }
-    }
-
-    /**
-     * Determine if URL is in approved list of URLs to load.
-     *
-     * @param url
-     * @return
-     */
-    public boolean isUrlWhiteListed(String url) {
-
-        // Check to see if we have matched url previously
-        if (this.whiteListCache.get(url) != null) {
-            return true;
-        }
-
-        // Look for match in white list
-        Iterator<Pattern> pit = this.whiteList.iterator();
-        while (pit.hasNext()) {
-            Pattern p = pit.next();
-            Matcher m = p.matcher(url);
-
-            // If match found, then cache it to speed up subsequent comparisons
-            if (m.find()) {
-                this.whiteListCache.put(url, true);
-                return true;
-            }
-        }
-        return false;
-    }
-
     /**
      * Load the url into the webview.
      *
@@ -532,8 +457,7 @@ public class CordovaWebView extends WebView {
         if (LOG.isLoggable(LOG.DEBUG) && !url.startsWith("javascript:")) {
             LOG.d(TAG, ">>> loadUrlNow()");
         }
-        boolean isDocument = this.baseUrl != null && url.indexOf(this.baseUrl) == 0;
-        if (url.startsWith("file://") || isDocument || url.startsWith("javascript:") || this.isUrlWhiteListed(url)) {
+        if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || url.startsWith("javascript:") || Config.isUrlWhiteListed(url)) {
             super.loadUrl(url);
         }
     }
@@ -681,7 +605,7 @@ public class CordovaWebView extends WebView {
         if (!openExternal) {
 
             // Make sure url is in whitelist
-            if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || isUrlWhiteListed(url)) {
+            if (url.startsWith("file://") || url.indexOf(this.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
                 // TODO: What about params?
 
                 // Clear out current url from history, since it will be replacing it
@@ -718,68 +642,14 @@ public class CordovaWebView extends WebView {
     }
 
     /**
-     * Load Cordova configuration from res/xml/cordova.xml.
+     * Check configuration parameters from Config.
      * Approved list of URLs that can be loaded into DroidGap
      *      <access origin="http://server regexp" subdomains="true" />
      * Log level: ERROR, WARN, INFO, DEBUG, VERBOSE (default=ERROR)
      *      <log level="DEBUG" />
      */
     private void loadConfiguration() {
-        Activity action = this.cordova.getActivity();
-        if(action == null)
-        {
-            LOG.i("CordovaLog", "There is no activity.  Is this on the lock screen?");
-            return;
-        }
-        int id = getResources().getIdentifier("config", "xml", this.cordova.getActivity().getPackageName());
-        if(id == 0)
-        {
-            id = getResources().getIdentifier("cordova", "xml", this.cordova.getActivity().getPackageName());   
-            Log.i("CordovaLog", "config.xml missing, reverting to cordova.xml");
-        }
-        if (id == 0) {
-            LOG.i("CordovaLog", "cordova.xml missing. Ignoring...");
-            return;
-        }
-        XmlResourceParser xml = getResources().getXml(id);
-        int eventType = -1;
-        while (eventType != XmlResourceParser.END_DOCUMENT) {
-            if (eventType == XmlResourceParser.START_TAG) {
-                String strNode = xml.getName();
-                if (strNode.equals("access")) {
-                    String origin = xml.getAttributeValue(null, "origin");
-                    String subdomains = xml.getAttributeValue(null, "subdomains");
-                    if (origin != null) {
-                        this.addWhiteListEntry(origin, (subdomains != null) && (subdomains.compareToIgnoreCase("true") == 0));
-                    }
-                }
-                else if (strNode.equals("log")) {
-                    String level = xml.getAttributeValue(null, "level");
-                    LOG.i("CordovaLog", "Found log level %s", level);
-                    if (level != null) {
-                        LOG.setLogLevel(level);
-                    }
-                }
-                else if (strNode.equals("preference")) {
-                    String name = xml.getAttributeValue(null, "name");
-                    String value = xml.getAttributeValue(null, "value");
-
-                    LOG.i("CordovaLog", "Found preference for %s=%s", name, value);
-                    Log.d("CordovaLog", "Found preference for " + name + "=" + value);
-
-                    // Save preferences in Intent
-                    this.cordova.getActivity().getIntent().putExtra(name, value);
-                }
-            }
-            try {
-                eventType = xml.next();
-            } catch (XmlPullParserException e) {
-                e.printStackTrace();
-            } catch (IOException e) {
-                e.printStackTrace();
-            }
-        }
-
+        // Config has already been loaded, and it stores these preferences on the Intent.
         if("false".equals(this.getProperty("useBrowserHistory", "true")))
         {
             //Switch back to the old browser history and state the six month policy
diff --git a/framework/src/org/apache/cordova/CordovaWebViewClient.java b/framework/src/org/apache/cordova/CordovaWebViewClient.java
index 63ab3255..7a7e6ed9 100755
--- a/framework/src/org/apache/cordova/CordovaWebViewClient.java
+++ b/framework/src/org/apache/cordova/CordovaWebViewClient.java
@@ -21,7 +21,6 @@ package org.apache.cordova;
 import java.util.Hashtable;
 
 import org.apache.cordova.api.CordovaInterface;
-import org.apache.cordova.api.PluginResult;
 
 import org.apache.cordova.api.LOG;
 import org.json.JSONException;
@@ -193,7 +192,7 @@ public class CordovaWebViewClient extends WebViewClient {
 
             // If our app or file:, then load into a new Cordova webview container by starting a new instance of our activity.
             // Our app continues to run.  When BACK is pressed, our app is redisplayed.
-            if (url.startsWith("file://") || url.startsWith("data:") || url.indexOf(this.appView.baseUrl) == 0 || this.appView.isUrlWhiteListed(url)) {
+            if (url.startsWith("file://") || url.startsWith("data:") || url.indexOf(this.appView.baseUrl) == 0 || Config.isUrlWhiteListed(url)) {
                 //This will fix iFrames
                 if (appView.useBrowserHistory || url.startsWith("data:"))
                     return false;
diff --git a/framework/src/org/apache/cordova/DroidGap.java b/framework/src/org/apache/cordova/DroidGap.java
index 6f16385f..175fe139 100755
--- a/framework/src/org/apache/cordova/DroidGap.java
+++ b/framework/src/org/apache/cordova/DroidGap.java
@@ -48,7 +48,6 @@ import android.view.View;
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
-import android.webkit.WebView;
 import android.webkit.WebViewClient;
 import android.widget.LinearLayout;
 
@@ -853,7 +852,7 @@ public class DroidGap extends Activity implements CordovaInterface {
 
         // If errorUrl specified, then load it
         final String errorUrl = me.getStringProperty("errorUrl", null);
-        if ((errorUrl != null) && (errorUrl.startsWith("file://") || this.appView.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
+        if ((errorUrl != null) && (errorUrl.startsWith("file://") || Config.isUrlWhiteListed(errorUrl)) && (!failingUrl.equals(errorUrl))) {
 
             // Load URL on UI thread
             me.runOnUiThread(new Runnable() {
@@ -921,11 +920,7 @@ public class DroidGap extends Activity implements CordovaInterface {
      * @return
      */
     public boolean isUrlWhiteListed(String url) {
-        // Check to see if we have matched url previously
-        if (this.appView != null) {
-            return this.appView.isUrlWhiteListed(url);
-        }
-        return false;
+        return Config.isUrlWhiteListed(url);
     }
 
     /*
diff --git a/framework/src/org/apache/cordova/FileTransfer.java b/framework/src/org/apache/cordova/FileTransfer.java
index 9bec20c9..d3e304f1 100644
--- a/framework/src/org/apache/cordova/FileTransfer.java
+++ b/framework/src/org/apache/cordova/FileTransfer.java
@@ -602,8 +602,8 @@ public class FileTransfer extends CordovaPlugin {
             return;
         }
         final boolean useHttps = url.getProtocol().toLowerCase().equals("https");
-        
-        if (!webView.isUrlWhiteListed(source)) {
+
+        if (!Config.isUrlWhiteListed(source)) {
             Log.w(LOG_TAG, "Source URL is not in white list: '" + source + "'");
             JSONObject error = createFileTransferError(CONNECTION_ERR, source, target, 401);
             callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.IO_EXCEPTION, error));
diff --git a/framework/src/org/apache/cordova/InAppBrowser.java b/framework/src/org/apache/cordova/InAppBrowser.java
index 886a95b0..0d834328 100644
--- a/framework/src/org/apache/cordova/InAppBrowser.java
+++ b/framework/src/org/apache/cordova/InAppBrowser.java
@@ -105,7 +105,7 @@ public class InAppBrowser extends CordovaPlugin {
                     Log.d(LOG_TAG, "in self");
                     // load in webview
                     if (url.startsWith("file://") || url.startsWith("javascript:") 
-                            || this.webView.isUrlWhiteListed(url)) {
+                            || Config.isUrlWhiteListed(url)) {
                         this.webView.loadUrl(url);
                     }
                     // load in InAppBrowser
@@ -531,4 +531,4 @@ public class InAppBrowser extends CordovaPlugin {
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/test/src/org/apache/cordova/test/actions/basicauth.java b/test/src/org/apache/cordova/test/actions/basicauth.java
index bd32d58f..ad739c9e 100755
--- a/test/src/org/apache/cordova/test/actions/basicauth.java
+++ b/test/src/org/apache/cordova/test/actions/basicauth.java
@@ -34,7 +34,8 @@ public class basicauth extends DroidGap {
         super.setAuthenticationToken(token, "browserspy.dk:80", "BrowserSpy.dk - HTTP Password Test");
 
         // Add web site to whitelist
-        super.appView.addWhiteListEntry("http://browserspy.dk*", true);
+        Config.init();
+        Config.addWhiteListEntry("http://browserspy.dk*", true);
 
         // Load test
         super.loadUrl("file:///android_asset/www/basicauth/index.html");