void NotifyWebAppisHosted(string webAppVersionString)
        {
            WebAppVersion = webAppVersionString;
            string jsResults;

            using (var context = new AutoJSContext(_browser.Window.JSContext))
                using (new JSAutoCompartment(context, (nsISupports)_browser.Window.DomWindow))
                {
                    context.EvaluateScript("hostedAppSetup();", out jsResults);
                }

            //This loads the last saved program. We know at this point that everything should be working in Blockly.
            if (!string.IsNullOrWhiteSpace(Settings.Default.SavedProgram))
            {
                string tempPath = IOPath.Combine(IOPath.GetTempPath(), IOPath.GetRandomFileName());
                Directory.CreateDirectory(tempPath);
                string tempLoadingFile = IOPath.Combine(tempPath, "temp_blocks.xml");
                using (var file = File.OpenWrite(tempLoadingFile))
                    using (var sw = new StreamWriter(file))
                    {
                        sw.Write(Settings.Default.SavedProgram);
                    }
                _tempPathsCreated.Add(tempPath);
                string fileUri = "file://" + new FileInfo(tempLoadingFile).FullName;

                using (var context = new AutoJSContext(_browser.Window.JSContext))
                    using (var compartment = new JSAutoCompartment(context, (nsISupports)_browser.Window.DomWindow))
                    {
                        string output;
                        context.EvaluateScript("load_by_url('" + fileUri.Replace("\\", "/") + "');", out output);
                    }
            }
        }
        void Upload_Click(object sender, RoutedEventArgs e)
        {
            string message;

            if (ValidateArduinoSetup(ArduinoPath, Programmers, SelectedProgrammer, ProgrammerPorts, SelectedPort, true, out message))
            {
                string jsResults;

                using (AutoJSContext context = new AutoJSContext(_browser.Window.JSContext))
                    using (JSAutoCompartment compartment = new JSAutoCompartment(context, (nsISupports)_browser.Window.DomWindow))
                    {
                        context.EvaluateScript("(Blockly.Generator.workspaceToCode('Arduino'))", out jsResults);
                    }

                System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(_browser.ClientRectangle.Width, _browser.ClientRectangle.Height);
                _browser.DrawToBitmap(bmp, _browser.ClientRectangle);

                var screenshot = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                    bmp.GetHbitmap(),
                    IntPtr.Zero,
                    System.Windows.Int32Rect.Empty,
                    BitmapSizeOptions.FromWidthAndHeight(bmp.Width, bmp.Height));

                //The following is like 3 card Monty with threads and contexts, but it does work ;)
                var loadingWindow = new UploadingWindow()
                {
                    Owner = this, WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner
                };

                loadingWindow.BlocksImage.Source = screenshot;
                IsEnabled = false;

                loadingWindow.Loaded += (s, ev) => {
                    Task.Run(() =>
                    {
                        string errorText;
                        bool result = SendToArduino(true, jsResults, out errorText);
                        Dispatcher.InvokeAsync(() =>
                        {
                            loadingWindow.Close();
                            IsEnabled = true;
                            if (result)
                            {
                                MessageBox.Show(this, "Success!", "Upload Complete!", MessageBoxButton.OK, MessageBoxImage.Information);
                            }
                            else
                            {
                                MessageBox.Show(this, "There were problems:\n" + errorText ?? "UNKNOWN ERROR", "Upload Failed :(", MessageBoxButton.OK,
                                                MessageBoxImage.Error);
                            }
                        });
                    });
                };
                loadingWindow.ShowDialog();
            }
        }
        void OpenInIDE_Click(object sender, RoutedEventArgs e)
        {
            string message;

            if (ValidateArduinoSetup(ArduinoPath, Programmers, SelectedProgrammer, ProgrammerPorts, SelectedPort, false, out message))
            {
                string jsResults;

                using (AutoJSContext context = new AutoJSContext(_browser.Window.JSContext))
                    using (JSAutoCompartment compartment = new JSAutoCompartment(context, (nsISupports)_browser.Window.DomWindow))
                    {
                        context.EvaluateScript("(Blockly.Generator.workspaceToCode('Arduino'))", out jsResults);
                    }
                string errorText;
                SendToArduino(false, jsResults, out errorText);
            }
            else
            {
                MessageBox.Show(message, "There is a problem with your setup");
            }
        }
        void Load_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog()
            {
                Filter = "Robot Block Files | *.blocks"
            };

            if (dlg.ShowDialog(this) ?? false)
            {
                string tempPath = IOPath.Combine(IOPath.GetTempPath(), IOPath.GetRandomFileName());
                Directory.CreateDirectory(tempPath);
                string tempLoadingFile = IOPath.Combine(tempPath, "temp_blocks.xml");
                File.Copy(dlg.FileName, tempLoadingFile, true);
                _tempPathsCreated.Add(tempPath);
                string fileUri = "file://" + new FileInfo(tempLoadingFile).FullName;

                using (var context = new AutoJSContext(_browser.Window.JSContext))
                    using (var compartment = new JSAutoCompartment(context, (nsISupports)_browser.Window.DomWindow))
                    {
                        string output;
                        context.EvaluateScript("load_by_url('" + fileUri.Replace("\\", "/") + "');", out output);
                    }
            }
        }