private static void LoadPlugin(PluginInfo pi, IForwardDestinationHandler ifdh)

        {
            try

            {
                // load if not already loaded

                if (ifdh == null)

                {
                    PluginFinder pf = new PluginFinder();

                    ifdh = pf.Load <IForwardDestinationHandler>(pi, ignoreList);
                }



                if (ifdh != null)

                {
                    // for the 'path' value, we still want to use the userprofile directory no matter where the plugin was loaded from

                    // the reason is that the 'path' is where plugin settings will be saved, so it needs to be user writable and user-specific

                    string path = Path.Combine(userForwarderDirectory, Growl.CoreLibrary.PathUtility.GetSafeFolderName(ifdh.Name));



                    // check to make sure this plugin was not loaded from another directory already

                    if (!loadedPlugins.ContainsKey(path))

                    {
                        loadedPlugins.Add(pi.FolderPath, pi);

                        if (!loadedPlugins.ContainsKey(path))
                        {
                            loadedPlugins.Add(path, pi);                                   // link by the settings path as well so we can detect duplicate plugins in other folders
                        }
                        loadedPluginsList.Add(pi);



                        LoadInternal(ifdh, pi.FolderPath, path);
                    }

                    else

                    {
                        // plugin was not valid

                        Utility.WriteDebugInfo(String.Format("Forwarder not loaded: '{0}' - Duplicate plugin was already loaded from another folder", pi.FolderPath));
                    }
                }

                else

                {
                    // plugin was not valid

                    Utility.WriteDebugInfo(String.Format("Forwarder not loaded: '{0}' - Does not implement IForwardDestinationHandler interface", pi.FolderPath));
                }
            }

            catch (Exception ex)

            {
                // suppress any per-plugin loading exceptions

                Utility.WriteDebugInfo(String.Format("Forwarder failed to load: '{0}' - {1} - {2}", pi.FolderPath, ex.Message, ex.StackTrace));
            }
        }
        private static void LoadPlugin(PluginInfo pi, IForwardDestinationHandler ifdh)
        {
            try
            {
                // load if not already loaded
                if (ifdh == null)
                {
                    PluginFinder pf = new PluginFinder();
                    ifdh = pf.Load<IForwardDestinationHandler>(pi, ignoreList);
                }

                if (ifdh != null)
                {
                    // for the 'path' value, we still want to use the userprofile directory no matter where the plugin was loaded from
                    // the reason is that the 'path' is where plugin settings will be saved, so it needs to be user writable and user-specific
                    string path = Path.Combine(userForwarderDirectory, Growl.CoreLibrary.PathUtility.GetSafeFolderName(ifdh.Name));

                    // check to make sure this plugin was not loaded from another directory already
                    if (!loadedPlugins.ContainsKey(path))
                    {
                        loadedPlugins.Add(pi.FolderPath, pi);
                        if (!loadedPlugins.ContainsKey(path)) loadedPlugins.Add(path, pi); // link by the settings path as well so we can detect duplicate plugins in other folders
                        loadedPluginsList.Add(pi);

                        LoadInternal(ifdh, pi.FolderPath, path);
                    }
                    else
                    {
                        // plugin was not valid
                        Utility.WriteDebugInfo(String.Format("Forwarder not loaded: '{0}' - Duplicate plugin was already loaded from another folder", pi.FolderPath));
                    }
                }
                else
                {
                    // plugin was not valid
                    Utility.WriteDebugInfo(String.Format("Forwarder not loaded: '{0}' - Does not implement IForwardDestinationHandler interface", pi.FolderPath));
                }
            }
            catch (Exception ex)
            {
                // suppress any per-plugin loading exceptions
                Utility.WriteDebugInfo(String.Format("Forwarder failed to load: '{0}' - {1} - {2}", pi.FolderPath, ex.Message, ex.StackTrace));
            }
        }
        public T Load <T>(PluginInfo pi, List <string> ignoreList) where T : class
        {
            //--DateTime st = DateTime.Now;

            T plugin = null;

            try
            {
                //--Console.WriteLine("PluginFinder.Load() 1: {0}", (DateTime.Now - st).TotalSeconds);

                string[] dlls = Directory.GetFiles(pi.FolderPath, "*.dll");

                // since we are using the static AppDomain data and referenceAssemblies collection, we have to lock this section
                lock (locker)
                {
                    // remember which folder we are currently processing
                    AppDomain.CurrentDomain.SetData(CURRENTLY_SEARCHING_PLUGIN_PATH, pi.FolderPath);

                    // we have to load any referenced assemblies. these include anything
                    // that is not the target assembly or Growl base assemblies
                    Dictionary <string, Assembly> assemblies = new Dictionary <string, Assembly>();
                    for (int d = 0; d < dlls.Length; d++)
                    {
                        string dllFullPath = dlls[d];
                        string dllFileName = Path.GetFileName(dllFullPath).ToLower();

                        bool ignore = false;
                        if (ignoreList != null && ignoreList.Contains(dllFileName))
                        {
                            ignore = true;
                        }
                        if (dllFullPath == pi.AssemblyPath)
                        {
                            ignore = true;
                        }

                        // dont add the common assemblies to the list so we dont waste time looking through their types
                        if (!ignore)
                        {
                            Assembly assembly = LoadAssembly(dllFullPath);
                            assemblies.Add(assembly.FullName, assembly);
                        }
                    }
                    // remember which assemblies we loaded for this display
                    referencedAssemblies.Add(pi.FolderPath, assemblies);

                    //--Console.WriteLine("PluginFinder.Load() 2: {0}", (DateTime.Now - st).TotalSeconds);

                    Assembly targetAssembly = LoadAssembly(pi.AssemblyPath);

                    //--Console.WriteLine("PluginFinder.Load() 3: {0}", (DateTime.Now - st).TotalSeconds);

                    // now that all required assemblies are loaded, we can instantiate the correct type
                    Type type = targetAssembly.GetType(pi.TypeName);
                    if (type != null)
                    {
                        plugin = CreateInstance(type, BindingFlags.Public | BindingFlags.Instance | BindingFlags.CreateInstance, new object[] { }) as T;
                    }

                    //--Console.WriteLine("PluginFinder.Load() 4: {0}", (DateTime.Now - st).TotalSeconds);
                }
            }
            catch (Exception ex)
            {
                // we will still rethrow this (since it is probably pretty bad and we want the user to know about it),
                // but we want to log that it happened so we know why the app crashed
                Utility.WriteDebugInfo(String.Format("The plugin '{0}-{1}' at {2} could not be loaded. {3}", pi.AssemblyName, pi.TypeName, pi.FolderPath, ex.ToString()));
                throw;
            }
            finally
            {
                // clean up a bit
                referencedAssemblies.Remove(pi.FolderPath);
                AppDomain.CurrentDomain.SetData(CURRENTLY_SEARCHING_PLUGIN_PATH, null);
            }

            //--Console.WriteLine("PluginFinder.Load() 5: {0}", (DateTime.Now - st).TotalSeconds);

            return(plugin);
        }
        private static void LoadFolder(string folder)
        {
            try
            {
                if (!loadedPlugins.ContainsKey(folder))
                {
                    PluginFinder pf = new PluginFinder();
                    IForwardDestinationHandler plugin = pf.Search<IForwardDestinationHandler>(folder, CheckType, ignoreList);
                    if (plugin != null)
                    {
                        Type type = plugin.GetType();
                        PluginInfo pi = new PluginInfo(folder, type);

                        LoadPlugin(pi, plugin);
                    }
                }
            }
            catch (Exception ex)
            {
                // suppress any per-plugin loading exceptions
                Utility.WriteDebugInfo(String.Format("Plugin failed to load: '{0}' - {1} - {2}", folder, ex.Message, ex.StackTrace));
            }
        }