/// <summary>
        /// Scan the folder and instance all classes that dlls contain within them
        /// </summary>
        /// <param name="TargetFolder">Load in this folder for shared libraries / dlls</param>
        /// <param name="SharedLibraryContains">any potential plugin to load must have this in the dll name</param>
        /// <param name="ClassNameContains">only instance classes with this string somewhere in the same</param>
        public void ScanFolder(string TargetFolder,
                               PluginFilterCheck CheckMe,
                               string SharedLibraryContains,
                               TargetClassLoadName CheckClassInfo,
                               string ClassNameContains)
        {
            var Targets = GetValidExternTargets(TargetFolder, CheckMe, SharedLibraryContains);

            if (Targets.Count > 0)
            {
                if (CheckClassInfo == null)
                {
                    foreach (string TargetSharedLib in Targets)
                    {
                        LoadedFileHandliers.AddRange(LoadAllPlugins(ClassNameContains, TargetSharedLib));
                    }
                }
                else
                {
                    foreach (string TargetShareLib in Targets)
                    {
                        LoadedFileHandliers.AddRange(LoadAllPlugins(CheckClassInfo, TargetShareLib));
                    }
                }
            }
        }
        public List <T> LoadAllPlugins(TargetClassLoadName ClassNameFilter, string DllLocation)
        {
            string SubName = "Container for plugins contained in " + Path.GetFileNameWithoutExtension(DllLocation);
            T      first   = (LoadPlugin(ClassNameFilter, string.Empty, null, null, DllLocation, SubName, 1, out List <T> NoJunk));

            NoJunk.Add(first);
            return(NoJunk);
        }
        /// <summary>
        /// the generic load routine for the system. The exported routines lead here
        /// </summary>
        /// <param name="TargetFormatClassCheck">specific null to skip this check. Called to see if the exported type is a match <seealso cref="TargetClassLoadName"/></param>
        /// <param name="TargetFormatClassString">if TargetFormatClassCheck is null checked class names are compaired against it</param>
        /// <param name="VerifyCallback">prevent unwanted assemblys from being used. <seealso cref="AssemblyCheck"/></param>
        /// <param name="VerifyAssemblyString">if Verifycallback is null, this is case sensisite compared with the FullName of the loaded assembly. No match means no go</param>
        /// <param name="DllLocation">load the dll from here</param>
        /// <param name="SubDomain">name of AppDomain created from the parent subdomain</param>
        /// <param name="MaxOverflow">load nore than MaxOverflow if > 0. Set negative to disable cap</param>
        /// <param name="Overflow">on exit contained additional loaded and instanced types</param>
        /// <returns></returns>
        private T LoadPlugin(TargetClassLoadName TargetFormatClassCheck,
                             string TargetFormatClassString,
                             AssemblyCheck VerifyCallback,
                             string VerifyAssemblyString,
                             string DllLocation,
                             string SubDomain,
                             int MaxOverflow,
                             out List <T> Overflow)
        {
            T Iterate = null;
            T ret     = null;

            Overflow = null;
            if (MaxOverflow < 0)
            {
                Overflow = new List <T>();
            }

            /*
             * redundant but get point accross
             * if (MaxOverflow == 0)
             * {
             *  Overflow = null;
             * }*/

            if (MaxOverflow >= 1)
            {
                Overflow = new List <T>(MaxOverflow);
            }

            Tool_DuplicateDomain(FormatContainer, SubDomain, out AppDomain Probe);

            AssemblyResolver_DynamicClassLoader tiny = new AssemblyResolver_DynamicClassLoader();

            Probe.AssemblyResolve += new ResolveEventHandler(tiny.Probe_AssemblyResolve);

            Assembly Dll = Probe.Load(DllLocation);

            if (VerifyCallback != null)
            {
                if (VerifyCallback(Dll) == false)
                {
                    throw new InvalidOperationException("Dll: " + Path.GetFileName(DllLocation) + " did not pass VerifyCheck");
                }
            }
            else
            {
                if (VerifyAssemblyString != null)
                {
                    if (Dll.FullName.Contains(VerifyAssemblyString) == false)
                    {
                        throw new InvalidOperationException("Dll: " + Path.GetFileName(DllLocation) + " did not pass VerifyCheck");
                    }
                }
            }


            foreach (Type DllType in  Dll.GetExportedTypes())
            {
                /*
                 * FUTURE ME: PAST ME WAS SLEEPY.
                 * This code is indended to check 3 scenerios for a match
                 *
                 *  #1
                 * TargetFormatClassCheck delegate is not null and returns true on call
                 *
                 * #2
                 *  TargetFormatClassCheck delegate is null, and the string is contained within the type's fullname if not zero
                 *
                 *  #3
                 *  both TargetClassCheck delegate is null and the string is null (this matches any)
                 *
                 *
                 *  Reason at the time is to consalodate the instance creation code on  match
                 *  YOUR THANK ME LATER FOR THIS COMMENT,
                 *  PAST ME
                 *
                 *      Follow Up:  Catch Generic Routines and things man or the .net runtime was not ment to instance in a Try Catch block
                 */
                /*if (((TargetFormatClassCheck != null) &&
                 * (TargetFormatClassCheck(DllType.FullName, DllType.GetTypeInfo()) == true))
                 ||
                 || ((TargetFormatClassString != null)) && ((TargetFormatClassString != null) && (DllType.FullName.Contains(TargetFormatClassString) == true))
                 ||
                 ||(TargetFormatClassString == null) && (TargetFormatClassCheck == null)) */

                if (TargetFormatClassCheck != null)
                {
                    if (TargetFormatClassCheck(DllType.FullName, DllType.GetTypeInfo()) == false)
                    {
                        continue;
                    }
                }
                if (TargetFormatClassString != null)
                {
                    if (DllType.FullName.Contains(TargetFormatClassString) == false)
                    {
                        continue;
                    }
                }


                {
                    // it's a match
                    Iterate = new T();
                    {
                        Iterate.Domain         = Probe;
                        Iterate.Handler        = Activator.CreateInstance(DllType);
                        Iterate.HandlerType    = DllType;
                        Iterate.LoadedAssembly = Dll;
                    };
                    if (ret == null)
                    {
                        ret = Iterate;
                        if (MaxOverflow == 0)
                        {
                            break;
                        }
                        else
                        {
                            if (MaxOverflow > 0)
                            {
                                MaxOverflow--;
                            }
                        }
                    }
                    else
                    {
                        Overflow.Add(Iterate);
                        MaxOverflow--;
                    }
                }
            }


            if (ret == null)
            {
                // no matches
                AppDomain.Unload(Probe);
                Overflow.Clear();
                Overflow = null;
            }
            return(ret);
        }
        /// <summary>
        /// Load an instanced class that the callback routine approves
        /// </summary>
        /// <param name="CheckName">delege to examine with. </param>
        /// <param name="DllLocation">assembly or dll to load from</param>
        /// <returns></returns>
        public T LoadPlugin(TargetClassLoadName CheckName, string DllLocation)
        {
            string SubName = "Container for " + CheckName + " plugin";

            return(LoadPlugin(CheckName, null, null, null, DllLocation, SubName, 0, out List <T> _));
        }