public void ThenAppDomainAssemblyResolveEventSubscriberCountShouldBeZero()
            {
                var testNamespace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                var testClassName = MethodBase.GetCurrentMethod().Name;

                Action <TestSetup> testSetup = (ts) =>
                {
                    // arrange
                    var testSource               = @"
                    namespace " + testNamespace + @"
                    {
                        using System;

                        public class " + testClassName + @" : MarshalByRefObject
                        {
                        }
                    }";
                    var testEmbeddedResources    = new string[] { };
                    var testReferencedAssemblies = new string[] { "System.dll" };
                    var testBinary               = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(testSource, testEmbeddedResources, testReferencedAssemblies, new DirectoryInfo(ts.TestAppDomain.BaseDirectory));

                    // act
                    var proxy = ts.TestAppDomain.CreateInstanceFromAndUnwrap(testBinary.FullName, string.Format("{0}.{1}", testNamespace, testClassName));

                    // assert
                    GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasAssemblyResolveEventSubscribers(0, ts.ParentAppDomain);
                    GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasAssemblyResolveEventSubscribers(0, ts.TestAppDomain);
                };

                GivenAnEmbeddedAssemblyLoader.ExecuteTestInsideTestAppDomain(testSetup);
            }
            public void FromMultipleThreadsThenAppDomainAssemblyResolveEventSubscriberCountShouldBeOne()
            {
                var testNamespace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                var testClassName = MethodBase.GetCurrentMethod().Name;

                Action <TestSetup> testSetup = (ts) =>
                {
                    // arrange
                    var testSource               = @"
                    namespace " + testNamespace + @"
                    {
                        using System;
                        using System.Collections.Generic;
                        using System.Threading;
                        using EmbeddedFx;

                        public class " + testClassName + @" : MarshalByRefObject
                        {
                            private IList<A> InstancesOfA;

                            public " + testClassName + @"()
                            {
                                this.InstancesOfA = new List<A>();
                                new Thread(this.SleepForFiveHundredMilliseconds).Start();
                                new Thread(this.SleepForFiveHundredMilliseconds).Start();
                                new Thread(this.SleepForFiveHundredMilliseconds).Start();
                                Thread.Sleep(2000);
                            }

                            private void SleepForFiveHundredMilliseconds()
                            {
                                this.InstancesOfA.Add(new A());
                            }

                            private class A
                            {
                                static A()
                                {
                                    EmbeddedAssemblyLoader.Register();
                                    Thread.Sleep(500);
                                }
                            }
                        }
                    }";
                    var testEmbeddedResources    = new string[] { };
                    var testReferencedAssemblies = new string[] { "System.dll", "EmbeddedFx.dll" };
                    var testBinary               = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(testSource, testEmbeddedResources, testReferencedAssemblies, new DirectoryInfo(ts.TestAppDomain.BaseDirectory));

                    // act
                    var proxy = ts.TestAppDomain.CreateInstanceFromAndUnwrap(testBinary.FullName, string.Format("{0}.{1}", testNamespace, testClassName));

                    // assert
                    GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasAssemblyResolveEventSubscribers(0, ts.ParentAppDomain);
                    GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasAssemblyResolveEventSubscribers(1, ts.TestAppDomain);
                };

                GivenAnEmbeddedAssemblyLoader.ExecuteTestInsideTestAppDomain(testSetup);
            }
            public void AndHasItsOwnAssemblyResolveEventHandlerThenAppDomainAssemblyResolveEventSubscriberCountShouldBeTwo()
            {
                var testNamespace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                var testClassName = MethodBase.GetCurrentMethod().Name;

                Action <TestSetup> testSetup = (ts) =>
                {
                    // arrange
                    var testSource               = @"
                    namespace " + testNamespace + @"
                    {
                        using System;
                        using System.Reflection;
                        using EmbeddedFx;

                        public class " + testClassName + @" : MarshalByRefObject
                        {
                            static " + testClassName + @"()
                            {
                                AppDomain.CurrentDomain.AssemblyResolve += " + testClassName + @".OwnAssemblyResolveEventHandler;
                                EmbeddedAssemblyLoader.Register();
                                EmbeddedAssemblyLoader.Register();
                                EmbeddedAssemblyLoader.Register();
                            }

                            private static Assembly OwnAssemblyResolveEventHandler(object sender, ResolveEventArgs args)
                            {
                                return null;
                            }
                        }
                    }";
                    var testEmbeddedResources    = new string[] { };
                    var testReferencedAssemblies = new string[] { "System.dll", "EmbeddedFx.dll" };
                    var testBinary               = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(testSource, testEmbeddedResources, testReferencedAssemblies, new DirectoryInfo(ts.TestAppDomain.BaseDirectory));

                    // act
                    var proxy = ts.TestAppDomain.CreateInstanceFromAndUnwrap(testBinary.FullName, string.Format("{0}.{1}", testNamespace, testClassName));

                    // assert
                    GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasAssemblyResolveEventSubscribers(0, ts.ParentAppDomain);
                    GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasAssemblyResolveEventSubscribers(2, ts.TestAppDomain);
                };

                GivenAnEmbeddedAssemblyLoader.ExecuteTestInsideTestAppDomain(testSetup);
            }
            public void ThenEmbeddedFxShouldBeLoadedIntoAppDomain()
            {
                var testNamespace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                var testClassName = MethodBase.GetCurrentMethod().Name;

                Action <TestSetup> testSetup = (ts) =>
                {
                    // arrange
                    var testSource               = @"
                        namespace " + testNamespace + @"
                        {
                            using System;
                            using EmbeddedFx;

                            public class " + testClassName + @" : MarshalByRefObject
                            {
                                static " + testClassName + @"()
                                {
                                    EmbeddedAssemblyLoader.Register();
                                }
                            }
                        }";
                    var testEmbeddedResources    = new string[] { };
                    var testReferencedAssemblies = new string[] { "System.dll", "EmbeddedFx.dll" };
                    var testBinary               = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(testSource, testEmbeddedResources, testReferencedAssemblies, new DirectoryInfo(ts.TestAppDomain.BaseDirectory));

                    // act
                    var proxy = ts.TestAppDomain.CreateInstanceFromAndUnwrap(testBinary.FullName, string.Format("{0}.{1}", testNamespace, testClassName));

                    // assert
                    var embeddedFxAssemblyName = AssemblyName.GetAssemblyName(new FileInfo("EmbeddedFx.dll").FullName);
                    GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasLoadedAssemblyName(false, ts.ParentAppDomain, embeddedFxAssemblyName);
                    GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasLoadedAssemblyName(true, ts.TestAppDomain, embeddedFxAssemblyName);
                };

                GivenAnEmbeddedAssemblyLoader.ExecuteTestInsideTestAppDomain(testSetup);
            }
            public void AndRefersToATypeThatIsEmbeddedAsAResourceShouldThrow()
            {
                var testNamespace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                var testClassName = MethodBase.GetCurrentMethod().Name;

                Action <TestSetup> testSetup = (ts) =>
                {
                    FileInfo libraryBinary = null;
                    try
                    {
                        // arrange
                        var librarySource               = @"
                            namespace " + testNamespace + @"
                            {
                                public class LibraryType
                                {
                                }
                            }";
                        var libraryEmbeddedResources    = new string[] { };
                        var libraryReferencedAssemblies = new string[] { };
                        libraryBinary = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(librarySource, libraryEmbeddedResources, libraryReferencedAssemblies, new DirectoryInfo(Path.GetTempPath()));

                        var testSource               = @"
                            namespace " + testNamespace + @"
                            {
                                using System;
 
                                public class " + testClassName + @" : MarshalByRefObject
                                {
                                    public " + testClassName + @"()
                                    {
                                        new LibraryType();
                                    }
                                }
                            }";
                        var testEmbeddedResources    = new string[] { libraryBinary.FullName };
                        var testReferencedAssemblies = new string[] { "System.dll", libraryBinary.FullName };
                        var testBinary               = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(testSource, testEmbeddedResources, testReferencedAssemblies, new DirectoryInfo(ts.TestAppDomain.BaseDirectory));

                        Exception thrownException = null;

                        // act
                        try
                        {
                            var proxy = ts.TestAppDomain.CreateInstanceFromAndUnwrap(testBinary.FullName, string.Format("{0}.{1}", testNamespace, testClassName));
                        }
                        catch (TargetInvocationException tie)
                        {
                            thrownException = tie;
                        }
                        catch (Exception e)
                        {
                            Assert.True(false, string.Format("An unexpected exception occurred: {0}", e.Message));
                        }

                        // assert
                        Assert.NotNull(thrownException);
                        Assert.NotNull(thrownException.InnerException);
                        Assert.Equal(typeof(FileNotFoundException), thrownException.InnerException.GetType());
                        Assert.Equal(string.Format("Could not load file or assembly '{0}' or one of its dependencies. The system cannot find the file specified.", AssemblyName.GetAssemblyName(libraryBinary.FullName)), thrownException.InnerException.Message);
                    }
                    finally
                    {
                        ActOnObject.IfNotNull(libraryBinary, (fi) => fi.Delete());
                    }
                };

                GivenAnEmbeddedAssemblyLoader.ExecuteTestInsideTestAppDomain(testSetup);
            }
            public void AndRefersToATypeThatIsEmbeddedAsANestedEmbeddedResourceThenEmbeddedResourceAssemblyShouldBeLoadedIntoAppDomain()
            {
                var testNamespace = MethodBase.GetCurrentMethod().DeclaringType.Namespace;
                var testClassName = MethodBase.GetCurrentMethod().Name;

                Action <TestSetup> testSetup = (ts) =>
                {
                    FileInfo nestedLibraryBinary = null;
                    FileInfo libraryBinary       = null;
                    try
                    {
                        // arrange
                        var nestedLibrarySource               = @"
                            namespace " + testNamespace + @"
                            {
                                public class NestedLibraryType
                                {
                                }
                            }";
                        var nestedLibraryEmbeddedResources    = new string[] { };
                        var nestedLibraryReferencedAssemblies = new string[] { };
                        nestedLibraryBinary = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(nestedLibrarySource, nestedLibraryEmbeddedResources, nestedLibraryReferencedAssemblies, new DirectoryInfo(Path.GetTempPath()));

                        var librarySource               = @"
                            namespace " + testNamespace + @"
                            {
                                public class LibraryType
                                {
                                }
                            }";
                        var libraryEmbeddedResources    = new string[] { nestedLibraryBinary.FullName };
                        var libraryReferencedAssemblies = new string[] { };
                        libraryBinary = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(librarySource, libraryEmbeddedResources, libraryReferencedAssemblies, new DirectoryInfo(Path.GetTempPath()));

                        var testSource               = @"
                            namespace " + testNamespace + @"
                            {
                                using System;
                                using EmbeddedFx;
 
                                public class " + testClassName + @" : MarshalByRefObject
                                {
                                    static " + testClassName + @"()
                                    {
                                        EmbeddedAssemblyLoader.Register();
                                    }

                                    public " + testClassName + @"()
                                    {
                                        new NestedLibraryType();
                                    }
                                }
                            }";
                        var testEmbeddedResources    = new string[] { libraryBinary.FullName };
                        var testReferencedAssemblies = new string[] { "System.dll", "EmbeddedFx.dll", libraryBinary.FullName, nestedLibraryBinary.FullName };
                        var testBinary               = GivenAnEmbeddedAssemblyLoader.CompileCodeIntoLocation(testSource, testEmbeddedResources, testReferencedAssemblies, new DirectoryInfo(ts.TestAppDomain.BaseDirectory));

                        // act
                        var proxy = ts.TestAppDomain.CreateInstanceFromAndUnwrap(testBinary.FullName, string.Format("{0}.{1}", testNamespace, testClassName));

                        // assert
                        var libraryBinaryAssemblyName = AssemblyName.GetAssemblyName(libraryBinary.FullName);
                        GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasLoadedAssemblyName(false, ts.ParentAppDomain, libraryBinaryAssemblyName);
                        GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasLoadedAssemblyName(false, ts.TestAppDomain, libraryBinaryAssemblyName);

                        var nestedLibraryBinaryAssemblyName = AssemblyName.GetAssemblyName(nestedLibraryBinary.FullName);
                        GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasLoadedAssemblyName(false, ts.ParentAppDomain, nestedLibraryBinaryAssemblyName);
                        GivenAnEmbeddedAssemblyLoader.AssertAppDomainHasLoadedAssemblyName(true, ts.TestAppDomain, nestedLibraryBinaryAssemblyName);
                    }
                    finally
                    {
                        ActOnObject.IfNotNull(libraryBinary, (fi) => fi.Delete());
                        ActOnObject.IfNotNull(nestedLibraryBinary, (fi) => fi.Delete());
                    }
                };

                GivenAnEmbeddedAssemblyLoader.ExecuteTestInsideTestAppDomain(testSetup);
            }