diff --git a/Plugins/Plugin.cs b/Plugins/Plugin.cs
index 10f3d319..445a074b 100644
--- a/Plugins/Plugin.cs
+++ b/Plugins/Plugin.cs
@@ -13,6 +13,7 @@ class Plugin{
         public string Version { get { return metadata["VERSION"]; } }
         public string Website { get { return metadata["WEBSITE"]; } }
         public string ConfigFile { get { return metadata["CONFIGFILE"]; } }
+        public string ConfigDefault { get { return metadata["CONFIGDEFAULT"]; } }
         public string RequiredVersion { get { return metadata["REQUIRES"]; } }
         public PluginGroup Group { get; private set; }
         public PluginEnvironment Environments { get; private set; }
@@ -31,13 +32,25 @@ public string FolderPath{
 
         public bool HasConfig{
             get{
-                return ConfigFile.Length > 0;
+                return ConfigFile.Length > 0 && GetFullPathIfSafe(ConfigFile).Length > 0;
             }
         }
 
         public string ConfigPath{
             get{
-                return HasConfig ? Path.Combine(path, ConfigFile) : "";
+                return HasConfig ? Path.Combine(path, ConfigFile) : string.Empty;
+            }
+        }
+
+        public bool HasDefaultConfig{
+            get{
+                return ConfigDefault.Length > 0 && GetFullPathIfSafe(ConfigDefault).Length > 0;
+            }
+        }
+
+        public string DefaultConfigPath{
+            get{
+                return HasDefaultConfig ? Path.Combine(path, ConfigDefault) : string.Empty;
             }
         }
 
@@ -50,6 +63,7 @@ public string ConfigPath{
             { "VERSION", "(unknown)" },
             { "WEBSITE", "" },
             { "CONFIGFILE", "" },
+            { "CONFIGDEFAULT", "" },
             { "REQUIRES", "*" }
         };
 
@@ -62,6 +76,18 @@ private Plugin(string path, PluginGroup group){
             this.Environments = PluginEnvironment.None;
         }
 
+        private void OnMetadataLoaded(){
+            string configPath = ConfigPath, defaultConfigPath = DefaultConfigPath;
+
+            if (configPath.Length > 0 && defaultConfigPath.Length > 0 && !File.Exists(configPath) && File.Exists(defaultConfigPath)){
+                try{
+                    File.Copy(defaultConfigPath, configPath, false);
+                }catch(Exception e){
+                    Program.HandleException("Could not generate a configuration file for '"+identifier+"' plugin.", e);
+                }
+            }
+        }
+
         public string GetScriptPath(PluginEnvironment environment){
             if (Environments.HasFlag(environment)){
                 string file = environment.GetScriptFile();
@@ -72,6 +98,28 @@ public string GetScriptPath(PluginEnvironment environment){
             }
         }
 
+        public string GetFullPathIfSafe(string relativePath){
+            string fullPath = Path.Combine(path, relativePath);
+
+            try{
+                string folderPathName = new DirectoryInfo(path).FullName;
+                DirectoryInfo currentInfo = new DirectoryInfo(fullPath);
+
+                while(currentInfo.Parent != null){
+                    if (currentInfo.Parent.FullName == folderPathName){
+                        return fullPath;
+                    }
+                    
+                    currentInfo = currentInfo.Parent;
+                }
+            }
+            catch{
+                // ignore
+            }
+
+            return string.Empty;
+        }
+
         public override string ToString(){
             return Identifier;
         }
@@ -166,6 +214,8 @@ private static bool LoadMetadata(string path, Plugin plugin, out string error){
                 return false;
             }
 
+            plugin.OnMetadataLoaded();
+
             error = string.Empty;
             return true;
         }
diff --git a/Plugins/PluginBridge.cs b/Plugins/PluginBridge.cs
index 8ece7e64..5b83b6b7 100644
--- a/Plugins/PluginBridge.cs
+++ b/Plugins/PluginBridge.cs
@@ -20,30 +20,7 @@ private void manager_Reloaded(object sender, PluginLoadEventArgs e){
 
         private string GetFullPathIfSafe(int token, string path){
             Plugin plugin = manager.GetPluginFromToken(token);
-            
-            if (plugin == null){
-                return string.Empty;
-            }
-
-            string fullPath = Path.Combine(plugin.FolderPath, path);
-
-            try{
-                string folderPathName = new DirectoryInfo(plugin.FolderPath).FullName;
-                DirectoryInfo currentInfo = new DirectoryInfo(fullPath);
-
-                while(currentInfo.Parent != null){
-                    if (currentInfo.Parent.FullName == folderPathName){
-                        return fullPath;
-                    }
-                    
-                    currentInfo = currentInfo.Parent;
-                }
-            }
-            catch{
-                // ignore
-            }
-
-            return string.Empty;
+            return plugin == null ? string.Empty : plugin.GetFullPathIfSafe(path);
         }
 
         public void WriteFile(int token, string path, string contents){
diff --git a/Resources/Scripts/plugins.js b/Resources/Scripts/plugins.js
index 134f00a0..bdb83c05 100644
--- a/Resources/Scripts/plugins.js
+++ b/Resources/Scripts/plugins.js
@@ -2,8 +2,13 @@
   //
   // Block: Setup a simple JavaScript object configuration loader.
   //
-  (function(){
-    var continueLoading = function(token, identifier, fileName, onSuccess, onFailure){
+  window.TDPF_loadConfigurationFile = function(pluginObject, fileNameUser, fileNameDefault, onSuccess, onFailure){
+    var identifier = pluginObject.$id;
+    var token = pluginObject.$token;
+
+    $TDP.checkFileExists(token, fileNameUser).then(exists => {
+      var fileName = exists ? fileNameUser : fileNameDefault;
+
       $TDP.readFile(token, fileName, true).then(contents => {
         var obj;
 
@@ -20,34 +25,13 @@
         onSuccess && onSuccess(obj);
       }).catch(err => {
         if (!(onFailure && onFailure(err))){
-          $TD.alert("warning", "Problem loading '"+fileName+"' file for '"+identifier+"' plugin: "+err);
+          $TD.alert("warning", "Problem loading '"+fileName+"' file for '"+identifier+"' plugin: "+err.message);
         }
       });
-    };
-    
-    window.TDPF_loadConfigurationFile = function(pluginObject, fileNameUser, fileNameDefault, onSuccess, onFailure){
-      var identifier = pluginObject.$id;
-      var token = pluginObject.$token;
-
-      $TDP.checkFileExists(token, fileNameUser).then(exists => {
-        if (!exists){
-          $TDP.readFile(token, fileNameDefault, true).then(contents => {
-            $TDP.writeFile(token, fileNameUser, contents);
-            continueLoading(token, identifier, fileNameUser, onSuccess, onFailure);
-          }).catch(err => {
-            if (!(onFailure && onFailure(err))){
-              $TD.alert("warning", "Problem generating '"+fileNameUser+"' file for '"+identifier+"' plugin: "+err);
-            }
-          });
-        }
-        else{
-          continueLoading(token, identifier, fileNameUser, onSuccess, onFailure);
-        }
-      }).catch(err => {
-        if (!(onFailure && onFailure(err))){
-          $TD.alert("warning", "Problem checking '"+fileNameUser+"' file for '"+identifier+"' plugin: "+err);
-        }
-      });
-    };
-  })();
+    }).catch(err => {
+      if (!(onFailure && onFailure(err))){
+        $TD.alert("warning", "Problem checking '"+fileNameUser+"' file for '"+identifier+"' plugin: "+err.message);
+      }
+    });
+  };
 })($TDP);
\ No newline at end of file