/// <summary>
        /// Finds all the plugin implementations of a given type and updates their status in
        /// the internal cache:
        ///
        /// `avaiallbePluginsCache` - Available to be used, but not enabled in the scene.
        /// `enabledPluginsCache` - Available to be used and enabled in the scene.
        /// `supportedPluginsCache` - Known plugins that are not yet available for use (likely has a dependency on a missing asset)
        /// </summary>
        /// <param name="T"></param>
        private void UpdatePluginStatus(Type T)
        {
            // Iterate over all the known plugins of this type
            IEnumerable <Type> plugins = ReflectionHelper.GetEnumerableOfType(T);

            foreach (Type pluginType in plugins)
            {
                // If any dependencies are present then provide enable/disable buttons, otherwise provide more info only
                AbstractPluginDefinition pluginDef = Activator.CreateInstance(pluginType) as AbstractPluginDefinition;
                if (pluginDef.AvailableForUse)
                {
                    bool isAvailable = true;
                    // See if there are any existing instances of this plugin in the scene
                    Component[]             components     = manager.GetComponentsInChildren(pluginDef.GetManagerType());
                    AbstractPluginManager[] pluginManagers = Array.ConvertAll(components, item => (AbstractPluginManager)item);

                    if (pluginManagers != null && pluginManagers.Count() != 0)
                    {
                        for (int i = 0; i < pluginManagers.Count(); i++)
                        {
                            AbstractPluginProfile pluginProfile = pluginManagers[i].m_pluginProfile;
                            if (pluginProfile != null && pluginDef.GetProfileTypeName().EndsWith(pluginProfile.GetType().Name))
                            {
                                AddToCache(enabledPluginsCache, pluginDef);
                                if (!pluginDef.MultipleAllowed)
                                {
                                    isAvailable = false;
                                }
                            }
                        }
                    }

                    if (isAvailable)
                    {
                        // There are no existing managers in the scene or multiple are allowed, show enable options
                        AddToCache(availablePluginsCache, pluginDef);
                    }
                }
                else
                {
                    AddToCache(supportedPluginsCache, pluginDef);
                }
            }
        }
        private void SetupDefaultSettings(AbstractPluginManager manager, string fromPath, string toPath)
        {
            Scene  scene     = EditorSceneManager.GetActiveScene();
            string sceneName = scene.name;

            if (!AssetDatabase.IsValidFolder(toPath + "/" + AssetDatabaseUtility.dataFolderName))
            {
                AssetDatabase.CreateFolder(toPath, AssetDatabaseUtility.dataFolderName);
            }

            string pluginFolder = fromPath.Split('/').First();
            string fullToPath   = toPath + "/" + AssetDatabaseUtility.dataFolderName + "/" + pluginFolder;

            if (!AssetDatabase.IsValidFolder(fullToPath))
            {
                AssetDatabase.CreateFolder(toPath + "/" + AssetDatabaseUtility.dataFolderName, pluginFolder);
            }

            try
            {
                string[] fileEntries = Directory.GetFiles(Application.dataPath + "/" + fromPath);
                foreach (string fileName in fileEntries)
                {
                    string temp      = fileName.Replace("\\", "/");
                    int    index     = temp.LastIndexOf("/");
                    string localPath = "Assets/" + fromPath;

                    if (index > 0)
                    {
                        localPath += temp.Substring(index);
                    }

                    UnityEngine.Object original = AssetDatabase.LoadAssetAtPath(localPath, typeof(ScriptableObject));
                    if (original != null)
                    {
                        string filename = Path.GetFileName(localPath);
                        filename = filename.Replace("_Default", "_" + sceneName);
                        if (AssetDatabase.GetMainAssetTypeAtPath(fullToPath + "/" + filename) == null)
                        {
                            AssetDatabase.CopyAsset(localPath, fullToPath + "/" + filename);
                        }
                    }

                    // if AbstractPluginProfile copy it into Profile

                    AbstractPluginProfile profile = (AbstractPluginProfile)AssetDatabase.LoadAssetAtPath(localPath, typeof(AbstractPluginProfile));
                    if (profile != null)
                    {
                        string filename = Path.GetFileName(localPath);
                        filename = filename.Replace("_Default", "_" + sceneName);
                        AssetDatabase.CopyAsset(localPath, toPath + "/" + AssetDatabaseUtility.dataFolderName + "/" + filename);

                        manager.Profile = profile;
                    }
                }
            }
            catch (Exception e)
            {
                Debug.LogError("Unable to copy plugin default settings. Digital Painting expects to find the default settings in " + fromPath + " see following exception for more information", this);
                Debug.LogException(e);
            }
        }