public static void Shutdown(string reason)
        {
            SendOrPostCallback cb = s =>
            {
                if (Interlocked.Exchange(ref _cefInitialized, 0) == 1)
                {
                    Logger.Info("CEF will shut down because {0}", reason);
                    var browsers = new List <ICefWebBrowser>(Browsers);
                    Logger.Info("Closing all open browsers.");

                    foreach (var browser in browsers)
                    {
                        try
                        {
                            browser.Dispose();
                        }
                        catch (Exception ex)
                        {
                            Logger.Error("Failed to close browser", ex);
                        }
                    }

                    Browsers.Clear();

                    Logger.Info("Shutting down CEF.");
                    _cefApp = null;

                    CefRuntime.Shutdown();
                }
            };

            var currentThreadId = Thread.CurrentThread.ManagedThreadId;

            if (currentThreadId != _initThread)
            {
                MainThreadContext.Send(cb, null);
            }
            else
            {
                cb(null);
            }
        }
        public static void Initialize(string cachePath             = null,
                                      string paragonPath           = null,
                                      string browserLanguage       = null,
                                      string authserverlist        = null,
                                      string authdelgatelist       = null,
                                      bool disableSpellChecking    = false,
                                      bool ignoreCertificateErrors = false,
                                      bool persistSessionCookies   = false)
        {
            if (IsInitialized)
            {
                Logger.Debug("CEF initialization aborted because it is already initialized .");
                return;
            }

            using (AutoStopwatch.TimeIt("Initializing runtime"))
            {
                if (Interlocked.CompareExchange(ref _cefInitializing, 1, 0) == 1)
                {
                    Logger.Debug("CEF initialization aborted because initialization is in progress");
                    return;
                }

                Logger.Debug("CEF is initializing");

                MainThreadContext = SynchronizationContext.Current;

                try
                {
                    var logPath = "cef.log";

                    _initThread = Thread.CurrentThread.ManagedThreadId;
                    if (!string.IsNullOrEmpty(cachePath))
                    {
                        logPath   = Path.Combine(cachePath, logPath);
                        cachePath = Path.Combine(cachePath, "cache");
                    }

                    var rendererPath = paragonPath ?? Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "paragon.renderer.exe");
                    if (!File.Exists(rendererPath))
                    {
                        rendererPath = Path.Combine(Environment.CurrentDirectory, "paragon.renderer.exe");
                    }

                    if (!File.Exists(rendererPath))
                    {
                        throw new CefRuntimeException("Unable to determine the path to paragon.renderer.exe");
                    }

                    var binPath = Path.GetDirectoryName(rendererPath);

                    if (!File.Exists(Path.Combine(binPath, "libcef.dll")))
                    {
                        throw new CefRuntimeException("Unable to determine the path to libcef.dll");
                    }

                    var settings = new CefSettings
                    {
                        SingleProcess            = false,
                        MultiThreadedMessageLoop = true,
                        IgnoreCertificateErrors  = ignoreCertificateErrors,
                        LogSeverity           = CefLogSeverity.Default,
                        LogFile               = logPath,
                        BrowserSubprocessPath = rendererPath,
                        Locale                = browserLanguage,
                        CachePath             = cachePath,
                        PersistSessionCookies = persistSessionCookies,
                        AuthServerWhitelist   = authserverlist,
                        AuthDelegateWhitelist = authdelgatelist,
                        ProductVersion        = string.Format("Paragon/{0} Chrome/{1}", Assembly.GetExecutingAssembly().GetName().Version, CefRuntime.ChromeVersion)
                    };

                    var argArray = Environment.GetCommandLineArgs();



                    List <string> appArgs = new List <string>();
                    appArgs.Add("--process-per-tab");

                    // Pass through Kerberos and proxy parameters.
                    for (int i = 0; i < argArray.Length; i++)
                    {
                        string a = argArray[i];
                        if (a.StartsWith("--enable-logging") ||
                            a.StartsWith("--v=") ||
                            a.Contains("proxy"))
                        {
                            appArgs.Add(a);
                        }
                    }
                    var argString = string.Join(",", appArgs.ToArray());
                    Logger.Info("Passing Args to CefApp: " + argString);
                    var args = new CefMainArgs(appArgs.ToArray());

                    _cefApp = new CefBrowserApplication(disableSpellChecking, browserLanguage);
                    _cefApp.RenderProcessInitialize += OnRenderProcessInitialize;

                    if (BeforeCefInitialize != null)
                    {
                        var ea = new CefInitializationEventArgs();
                        BeforeCefInitialize(null, ea);
                        settings.LogFile     = ea.LogFile;
                        settings.LogSeverity = ea.LogSeverity;
                        if (ea.RemoteDebuggingPort > 0)
                        {
                            settings.RemoteDebuggingPort = ea.RemoteDebuggingPort;
                        }
                    }

                    CefRuntime.Load();

                    var result = CefRuntime.ExecuteProcess(args, _cefApp, IntPtr.Zero);
                    if (result == -1)
                    {
                        CefRuntime.Initialize(args, settings, _cefApp, IntPtr.Zero);
                        Interlocked.Exchange(ref _cefInitialized, 1);
                        Logger.Info("CEF initialized successfully");
                    }
                    else
                    {
                        throw new CefRuntimeException("CEF initialization failed - CefRuntime.ExecuteProcess return code: " + result);
                    }
                }
                catch (CefRuntimeException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    Logger.Error("Error initializing CEF: " + e);
                    throw;
                }
                finally
                {
                    Interlocked.Exchange(ref _cefInitializing, 0);
                    if (!IsInitialized && _cefApp != null)
                    {
                        _cefApp = null;
                    }
                }
            }
        }