public async Task Start()
        {
            if (_appDomain != null || _bootstrapper != null)
                await Stop().ConfigureAwait(false);

            StopListeners();

            if (Directory.Exists(_destination))
                new DirectoryInfo(_destination).DeleteDirectoryAndChildren();

            DirectoryCopy(_source, _destination);

            foreach (var host in _hosts)
                await host.Prepare(_destination).ConfigureAwait(false);

            TransformConfigurationsIn(_destination, ".config", _environment);
            TransformConfigurationsIn(_destination, ".xml", _environment);

            _appDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, new AppDomainSetup
            {
                ConfigurationFile = $"{ApplicationName}.dll.config",
                PrivateBinPath = _destination,
                ApplicationBase = _destination
            });

            _bootstrapper = (RemoteBootstrapper)_appDomain
                .CreateInstanceAndUnwrap(typeof(RemoteBootstrapper).Assembly.FullName, typeof(RemoteBootstrapper).FullName);

            _bootstrapper.Initialize(_destination);
            _bootstrapper.Start(_environment, _hostArguments);

            var listener = new FileListener();

            var extensionsNeedingReload = new List<string>
            {
                ".dll",
                ".exe",
                ".config",
                ".xml"
            };

            listener.StartListening(_source, "*", async x =>
            {
                var extension = Path.GetExtension(x);
                if (extensionsNeedingReload.Contains(extension))
                {
                    await Recycle().ConfigureAwait(false);

                    return;
                }

                var relativePath = x.Replace(_source, "");

                if (relativePath.StartsWith("\\"))
                    relativePath = relativePath.Substring(1);

                var newPath = Path.Combine(_destination, relativePath);

                for (var i = 0; i < 10; i++)
                {
                    try
                    {
                        if (ShouldCopy(Path.GetDirectoryName(x)))
                            File.Copy(x, newPath, true);

                        break;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Failed copying file: {ex.Message}");
                        await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
                    }
                }
            });

            _fileListeners.Add(listener);
        }
        public async Task Start()
        {
            if (_appDomain != null || _bootstrapper != null)
            {
                await Stop().ConfigureAwait(false);
            }

            StopListeners();

            if (Directory.Exists(_destination))
            {
                new DirectoryInfo(_destination).DeleteDirectoryAndChildren();
            }

            DirectoryCopy(_source, _destination);

            foreach (var host in _hosts)
            {
                await host.Prepare(_destination).ConfigureAwait(false);
            }

            TransformConfigurationsIn(_destination, ".config", _environment);
            TransformConfigurationsIn(_destination, ".xml", _environment);

            _appDomain = AppDomain.CreateDomain(Guid.NewGuid().ToString(), null, new AppDomainSetup
            {
                ConfigurationFile = $"{ApplicationName}.dll.config",
                PrivateBinPath    = _destination,
                ApplicationBase   = _destination
            });

            _bootstrapper = (RemoteBootstrapper)_appDomain
                            .CreateInstanceAndUnwrap(typeof(RemoteBootstrapper).Assembly.FullName, typeof(RemoteBootstrapper).FullName);

            _bootstrapper.Initialize(_destination);
            _bootstrapper.Start(_environment, _hostArguments);

            var listener = new FileListener();

            var extensionsNeedingReload = new List <string>
            {
                ".dll",
                ".exe",
                ".config",
                ".xml"
            };

            listener.StartListening(_source, "*", async x =>
            {
                var extension = Path.GetExtension(x);
                if (extensionsNeedingReload.Contains(extension))
                {
                    await Recycle().ConfigureAwait(false);

                    return;
                }

                var relativePath = x.Replace(_source, "");

                if (relativePath.StartsWith("\\"))
                {
                    relativePath = relativePath.Substring(1);
                }

                var newPath = Path.Combine(_destination, relativePath);

                for (var i = 0; i < 10; i++)
                {
                    try
                    {
                        if (ShouldCopy(Path.GetDirectoryName(x)))
                        {
                            File.Copy(x, newPath, true);
                        }

                        break;
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"Failed copying file: {ex.Message}");
                        await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);
                    }
                }
            });

            _fileListeners.Add(listener);
        }