Merge remote-tracking branch 'hartwig-cordova/feature/appdeploy-wpsdk8.1'
diff --git a/README.md b/README.md
index de139b8..3c66ec5 100644
--- a/README.md
+++ b/README.md
@@ -22,7 +22,7 @@
 
 Apache Cordova for Windows Phone 8
 ===
-[![Build status](https://ci.appveyor.com/api/projects/status/apoby7i5j5xnmhy2)](https://ci.appveyor.com/project/Humbedooh/cordova-wp8)
+[![Build status](https://ci.appveyor.com/api/projects/status/apoby7i5j5xnmhy2/branch/master)](https://ci.appveyor.com/project/Humbedooh/cordova-wp8/branch/master)
 
 
 This repo includes code to build Apache Cordova applications that target Windows Phone 8 SDK.
diff --git a/appveyor.yml b/appveyor.yml
index bd55765..10203f3 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -20,8 +20,6 @@
 # appveyor file
 # http://www.appveyor.com/docs/appveyor-yml
 
-nodejs_version: 0.10
-
 install:
   - npm install
 
diff --git a/template/cordovalib/ConsoleHelper.cs b/template/cordovalib/ConsoleHelper.cs
index 3443821..72edfb2 100644
--- a/template/cordovalib/ConsoleHelper.cs
+++ b/template/cordovalib/ConsoleHelper.cs
@@ -38,13 +38,6 @@
             {
             }
 
-            if (!hasListener)
-            {
-                PhoneApplicationService.Current.Closing += OnServiceClosing;
-                hasListener = true;
-            }
-
-
             string script = @"(function(win) {
         function exec(msg) { window.external.Notify('ConsoleLog/' + msg); }
         var cons = win.console = win.console || {};
@@ -71,15 +64,6 @@
             }
         }
 
-        public void DetachHandler()
-        {
-            if (hasListener)
-            {
-                PhoneApplicationService.Current.Closing -= OnServiceClosing;
-                hasListener = false;
-            }
-        }
-
         public bool HandleCommand(string commandStr)
         {
             string output = commandStr.Substring("ConsoleLog/".Length);
@@ -96,5 +80,15 @@
             return true;
         }
 
+        public void AttachNativeHandlers()
+        {
+            PhoneApplicationService.Current.Closing += OnServiceClosing;
+        }
+
+        public void DetachNativeHandlers()
+        {
+            PhoneApplicationService.Current.Closing -= OnServiceClosing;
+        }
+
     }
 }
diff --git a/template/cordovalib/CordovaView.xaml.cs b/template/cordovalib/CordovaView.xaml.cs
index 5e790a3..9a22d0f 100644
--- a/template/cordovalib/CordovaView.xaml.cs
+++ b/template/cordovalib/CordovaView.xaml.cs
@@ -136,22 +136,6 @@
                 return;
             }
 
-
-            StartupMode mode = PhoneApplicationService.Current.StartupMode;
-
-            if (mode == StartupMode.Launch)
-            {
-                PhoneApplicationService service = PhoneApplicationService.Current;
-                service.Activated += new EventHandler<Microsoft.Phone.Shell.ActivatedEventArgs>(AppActivated);
-                service.Launching += new EventHandler<LaunchingEventArgs>(AppLaunching);
-                service.Deactivated += new EventHandler<DeactivatedEventArgs>(AppDeactivated);
-                service.Closing += new EventHandler<ClosingEventArgs>(AppClosing);
-            }
-            else
-            {
-
-            }
-
             // initializes native execution logic
             configHandler = new ConfigHandler();
             configHandler.LoadAppPackageConfig();
@@ -270,6 +254,18 @@
 
         void CordovaBrowser_Loaded(object sender, RoutedEventArgs e)
         {
+          
+            PhoneApplicationService service = PhoneApplicationService.Current;
+            service.Activated += new EventHandler<Microsoft.Phone.Shell.ActivatedEventArgs>(AppActivated);
+            service.Launching += new EventHandler<LaunchingEventArgs>(AppLaunching);
+            service.Deactivated += new EventHandler<DeactivatedEventArgs>(AppDeactivated);
+            service.Closing += new EventHandler<ClosingEventArgs>(AppClosing);
+
+            foreach (IBrowserDecorator iBD in browserDecorators.Values)
+            {
+                iBD.AttachNativeHandlers();
+            }
+
 
             this.bmHelper.ScrollDisabled = this.DisableBouncyScrolling;
 
@@ -322,6 +318,20 @@
             }
         }
 
+        private void CordovaBrowser_Unloaded(object sender, RoutedEventArgs e)
+        {
+            PhoneApplicationService service = PhoneApplicationService.Current;
+            service.Activated -= new EventHandler<Microsoft.Phone.Shell.ActivatedEventArgs>(AppActivated);
+            service.Launching -= new EventHandler<LaunchingEventArgs>(AppLaunching);
+            service.Deactivated -= new EventHandler<DeactivatedEventArgs>(AppDeactivated);
+            service.Closing -= new EventHandler<ClosingEventArgs>(AppClosing);
+
+            foreach (IBrowserDecorator iBD in browserDecorators.Values)
+            {
+                iBD.DetachNativeHandlers();
+            }
+        }
+
         void AttachHardwareButtonHandlers()
         {
             PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
@@ -524,21 +534,6 @@
             }
         }
 
-        private void CordovaBrowser_Unloaded(object sender, RoutedEventArgs e)
-        {
-            IBrowserDecorator console;
-            if (browserDecorators.TryGetValue("ConsoleLog", out console))
-            {
-                ((ConsoleHelper)console).DetachHandler();
-            }
-
-            PhoneApplicationService service = PhoneApplicationService.Current;
-            service.Activated -= new EventHandler<Microsoft.Phone.Shell.ActivatedEventArgs>(AppActivated);
-            service.Launching -= new EventHandler<LaunchingEventArgs>(AppLaunching);
-            service.Deactivated -= new EventHandler<DeactivatedEventArgs>(AppDeactivated);
-            service.Closing -= new EventHandler<ClosingEventArgs>(AppClosing);
-        }
-
         private void CordovaBrowser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
         {
             Debug.WriteLine("CordovaBrowser_NavigationFailed :: " + e.Uri.ToString());
@@ -546,10 +541,10 @@
 
         private void CordovaBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
         {
-           foreach(IBrowserDecorator iBD in browserDecorators.Values)
-           {
-               iBD.InjectScript();
-           }
+            foreach (IBrowserDecorator iBD in browserDecorators.Values)
+            {
+                iBD.InjectScript();
+            }
         }
 
         /// <summary>
@@ -576,5 +571,10 @@
                               (byte)(argb & 0xff));
             return clr;
         }
+
+        ~CordovaView()
+        {
+            //Debug.WriteLine("CordovaView is destroyed");
+        }
     }
 }
diff --git a/template/cordovalib/IBrowserDecorator.cs b/template/cordovalib/IBrowserDecorator.cs
index bc1dbee..8425865 100644
--- a/template/cordovalib/IBrowserDecorator.cs
+++ b/template/cordovalib/IBrowserDecorator.cs
@@ -26,5 +26,7 @@
         WebBrowser Browser { get; set; }
         void InjectScript();
         bool HandleCommand(string cmd);
+        void AttachNativeHandlers();
+        void DetachNativeHandlers();
     }
 }
diff --git a/template/cordovalib/NativeExecution.cs b/template/cordovalib/NativeExecution.cs
index 18ca910..fe35aea 100644
--- a/template/cordovalib/NativeExecution.cs
+++ b/template/cordovalib/NativeExecution.cs
@@ -52,21 +52,6 @@
 
             this.webBrowser = browser;
             this.commands = new List<BaseCommand>();
-            webBrowser.Unloaded += webBrowser_Unloaded;
-        }
-
-        /// <summary>
-        /// Detaches event handlers to prevent memory leak on page navigation
-        /// </summary>
-        void webBrowser_Unloaded(object sender, RoutedEventArgs e)
-        {
-            for (int i = commands.Count - 1; i >= 0; i--)
-            {
-                if (commands[i] != null)
-                {
-                    commands[i].DetachHandlers();
-                }
-            }
         }
 
         /// <summary>
@@ -115,6 +100,12 @@
                     return;
                 }
 
+                // TODO: consider removing custom script functionality at all since we already marked it as absolute (see BaseCommand)
+                EventHandler<ScriptCallback> OnCustomScriptHandler = delegate(object o, ScriptCallback script)
+                {
+                    this.InvokeScriptCallback(script);
+                };
+
                 EventHandler<PluginResult> OnCommandResultHandler = delegate(object o, PluginResult res)
                 {
                     if (res.CallbackId == null || res.CallbackId == commandCallParams.CallbackId)
@@ -123,6 +114,7 @@
                         if (!res.KeepCallback)
                         {
                             bc.RemoveResultHandler(commandCallParams.CallbackId);
+                            bc.OnCustomScript -= OnCustomScriptHandler;
                         }
                     }
                 };
@@ -130,11 +122,6 @@
                 //bc.OnCommandResult += OnCommandResultHandler;
                 bc.AddResultHandler(commandCallParams.CallbackId, OnCommandResultHandler);
 
-                EventHandler<ScriptCallback> OnCustomScriptHandler = delegate(object o, ScriptCallback script)
-                {
-                    this.InvokeScriptCallback(script);
-                };
-
                 bc.OnCustomScript += OnCustomScriptHandler;
 
                 ThreadStart methodInvokation = () =>
diff --git a/template/cordovalib/OrientationHelper.cs b/template/cordovalib/OrientationHelper.cs
index 299f9dd..0ec32fe 100644
--- a/template/cordovalib/OrientationHelper.cs
+++ b/template/cordovalib/OrientationHelper.cs
@@ -125,6 +125,16 @@
             // No commands are currently accepted.
             return true;
         }
+
+        public void AttachNativeHandlers()
+        {
+            // nothing todo
+        }
+
+        public void DetachNativeHandlers()
+        {
+            // nothing to do
+        }
     }
 
 
diff --git a/template/cordovalib/XHRHelper.cs b/template/cordovalib/XHRHelper.cs
index 35913eb..1d72367 100644
--- a/template/cordovalib/XHRHelper.cs
+++ b/template/cordovalib/XHRHelper.cs
@@ -342,5 +342,15 @@
 
             return false;
         }
+
+        public void AttachNativeHandlers()
+        {
+            // nothing todo
+        }
+
+        public void DetachNativeHandlers()
+        {
+            // nothing to do
+        }
     }
 }