cordova-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From purplecabb...@apache.org
Subject [2/4] [WP7] Goodbye, it has been fun. ;)
Date Tue, 06 May 2014 21:07:25 GMT
http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/CommandFactory.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/CommandFactory.cs b/wp7/template/cordovalib/CommandFactory.cs
deleted file mode 100644
index 4bd5a09..0000000
--- a/wp7/template/cordovalib/CommandFactory.cs
+++ /dev/null
@@ -1,128 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Collections.Generic;
-using WPCordovaClassLib.Cordova.Commands;
-using System.Reflection;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova
-{
-    /// <summary>
-    /// Provides functionality to create Cordova command by name.
-    /// </summary>
-    public static class CommandFactory
-    {
-        /// <summary>
-        /// Represents predefined namespace name for custom plugins
-        /// </summary>
-        private static readonly string CustomPluginNamespacePrefix = "Cordova.Extension.Commands.";
-
-        private static readonly string BaseCommandNamespacePrefix = "WPCordovaClassLib.Cordova.Commands.";
-
-        /// <summary>
-        /// Cache instantiated commands in a map.
-        /// </summary>
-
-        private static Dictionary<string, BaseCommand> commandMap = new Dictionary<string, BaseCommand>();
-
-        /// <summary>
-        /// Creates command using command class name. Returns null for unknown commands.
-        /// </summary>
-        /// <param name="service">Command class name, for example Device or Notification</param>
-        /// <returns>Command class instance or null</returns>
-        /// alias can be used as a namespace which is resolved + service
-        /// or it can be the fully qualified classname
-        /// or the classname in the current assembly
-        public static BaseCommand CreateByServiceName(string service, string alias="")
-        {
-
-            if (string.IsNullOrEmpty(service))
-            {
-                throw new ArgumentNullException("service", "service to create can't be null");
-            }
-
-            if (!commandMap.ContainsKey(service))
-            {
-                Type t = Type.GetType(BaseCommandNamespacePrefix + service);
-
-                if (t == null && !string.IsNullOrEmpty(alias))
-                {
-                    t = Type.GetType(alias);
-
-                    if (t == null)
-                    {
-                        t = Type.GetType(BaseCommandNamespacePrefix + alias);
-                    }
-
-                    if (t == null)
-                    {
-                        t = Type.GetType(alias + "." + service);
-                    }
-                }
-
-                // custom plugin could be defined in own namespace and assembly
-                if (t == null)
-                {
-                    string serviceFullName = service.Contains(".") ? service : CustomPluginNamespacePrefix + service;
-
-                    foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
-                    {
-                        // in this case service name represents full type name including namespace
-                        t = a.GetType(serviceFullName);
-
-                        if (t == null) // try the Commands Namespace
-                        {
-                            t = a.GetType(BaseCommandNamespacePrefix + service);
-                        }
-
-                        if (t != null)
-                        {
-                            break;
-                        }
-                    }
-                }
-
-                // unknown command, still didn't find it
-                if (t == null)
-                {
-                    Debug.WriteLine("Unable to locate command :: " + service);
-                    return null;
-                }
-
-                commandMap[service] = Activator.CreateInstance(t) as BaseCommand;
-            }
-
-            return commandMap[service];
-        }
-
-        public static void ResetAllCommands()
-        {
-            foreach (BaseCommand bc in commandMap.Values)
-            {
-                bc.OnReset();
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/ConfigHandler.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/ConfigHandler.cs b/wp7/template/cordovalib/ConfigHandler.cs
deleted file mode 100644
index 1fb7525..0000000
--- a/wp7/template/cordovalib/ConfigHandler.cs
+++ /dev/null
@@ -1,275 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Windows;
-using System.Windows.Resources;
-using System.Xml.Linq;
-
-namespace WPCordovaClassLib.CordovaLib
-{
-    class ConfigHandler
-    {
-        public class PluginConfig
-        {
-            public PluginConfig(string name, bool autoLoad = false, string className = "")
-            {
-                Name = name;
-                isAutoLoad = autoLoad;
-                ClassName = className;
-            }
-            public string Name;
-            public bool isAutoLoad;
-            public string ClassName;
-        }
-
-        protected Dictionary<string, PluginConfig> AllowedPlugins;
-        protected List<string> AllowedDomains;
-        protected Dictionary<string, string> Preferences;
-
-        public string ContentSrc { get; private set; }
-
-        protected bool AllowAllDomains = false;
-        protected bool AllowAllPlugins = false;
-
-        public ConfigHandler()
-        {
-            AllowedPlugins = new Dictionary<string, PluginConfig>();
-            AllowedDomains = new List<string>();
-            Preferences = new Dictionary<string, string>();
-        }
-
-        public string GetPreference(string key)
-        {
-            return Preferences.ContainsKey(key.ToLowerInvariant()) ? Preferences[key.ToLowerInvariant()] : null;
-        }
-
-        protected static string[] AllowedSchemes = {"http","https","ftp","ftps"};
-        protected bool SchemeIsAllowed(string scheme)
-        {
-            return AllowedSchemes.Contains(scheme);
-        }
-
-        protected string PathAndQuery(Uri uri)
-        {
-            string result = uri.LocalPath;
-            if (uri.Query.Length > 0)
-            {
-                result +=  uri.Query;
-            }
-            return result;
-        }
-
-        protected void AddWhiteListEntry(string origin, bool allowSubdomains)
-        {
-
-            if (origin == "*")
-            {
-                AllowAllDomains = true;
-            }
-
-            if (AllowAllDomains)
-            {
-                return;
-            }
-
-            string hostMatchingRegex = "";
-            string hostName;
-
-            try
-            {
-
-                Uri uri = new Uri(origin.Replace("*", "replaced-text"), UriKind.Absolute);
-
-                string tempHostName = uri.Host.Replace("replaced-text", "*");
-                //if (uri.HostNameType == UriHostNameType.Dns){}        
-                // starts with wildcard match - we make the first '.' optional (so '*.org.apache.cordova' will match 'org.apache.cordova')
-                if (tempHostName.StartsWith("*."))
-                {    //"(\\s{0}|*.)"
-                    hostName = @"\w*.*" + tempHostName.Substring(2).Replace(".", @"\.").Replace("*", @"\w*");
-                }
-                else
-                {
-                    hostName = tempHostName.Replace(".", @"\.").Replace("*", @"\w*");
-                }
-
-                //  "^https?://"
-                hostMatchingRegex = uri.Scheme + "://" + hostName + PathAndQuery(uri);
-                //Debug.WriteLine("Adding regex :: " + hostMatchingRegex);
-                AllowedDomains.Add(hostMatchingRegex);
-
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("Invalid Whitelist entry (probably missing the protocol):: " + origin);
-            }
-
-        }
-
-        /**   
-         
-         An access request is granted for a given URI if there exists an item inside the access-request list such that:
-
-            - The URI's scheme component is the same as scheme; and
-            - if subdomains is false or if the URI's host component is not a domain name (as defined in [RFC1034]), the URI's host component is the same as host; or
-            - if subdomains is true, the URI's host component is either the same as host, or is a subdomain of host (as defined in [RFC1034]); and
-            - the URI's port component is the same as port.
-         
-         **/
-
-        public bool URLIsAllowed(string url)
-        {
-            // easy case first
-            if (AllowAllDomains )
-            {
-                return true;
-            }
-            else
-            {
-                // start simple
-                Uri uri = new Uri(url,UriKind.RelativeOrAbsolute);
-                if (uri.IsAbsoluteUri)
-                {
-                    if (this.SchemeIsAllowed(uri.Scheme))
-                    {
-                        // additional test because our pattern will always have a trailing '/'
-                        string matchUrl = url;
-                        if (PathAndQuery(uri) == "/")
-                        {
-                            matchUrl = url + "/";
-                        }
-                        foreach (string pattern in AllowedDomains)
-                        {
-                            if (Regex.IsMatch(matchUrl, pattern))
-                            {
-                                // make sure it is at the start, and not part of the query string
-                                // special case :: http://some.other.domain/page.html?x=1&g=http://build.apache.org/
-                                if ( Regex.IsMatch(uri.Scheme + "://" +  uri.Host + "/", pattern) ||
-                                     (!Regex.IsMatch(PathAndQuery(uri), pattern)))
-                                {
-                                    return true;
-                                }
-                            }
-                        }
-                    }
-                }
-                else
-                {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        public string[] AutoloadPlugins
-        {
-            get
-            {
-                // TODO:
-                var res = from results in AllowedPlugins.TakeWhile(p => p.Value.isAutoLoad)
-                          select results.Value.Name;
-
-                return new string[] { "", "" };
-            }
-        }
-
-        public string GetNamespaceForCommand(string key)
-        {
-            if(AllowedPlugins.Keys.Contains(key))
-            {
-                return AllowedPlugins[key].Name;
-            }
-             
-            return "";
-        }
-
-        public bool IsPluginAllowed(string key)
-        {
-            return AllowAllPlugins || AllowedPlugins.Keys.Contains(key);
-        }
-
-        private void LoadPluginFeatures(XDocument document)
-        {
-            var features = from f in document.Descendants()
-                           where f.Name.LocalName == "feature"
-                           select f;
-
-            foreach (var feature in features)
-            {
-                string name = (string)feature.Attribute("name");
-                var values = from results in feature.Descendants()
-                             where results.Name.LocalName == "param" && ((string)results.Attribute("name") == "wp-package")
-                             select results;
-
-                var value = values.FirstOrDefault();
-                if (value != null)
-                {
-                    string key = (string)value.Attribute("value");
-                    Debug.WriteLine("Adding feature.value=" + key);
-                    var onload = value.Attribute("onload");
-                    PluginConfig pConfig = new PluginConfig(key, onload != null && onload.Value == "true");
-                    AllowedPlugins[name] = pConfig;
-                }
-            }
-        }
-
-        public void LoadAppPackageConfig()
-        {
-            StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri("config.xml", UriKind.Relative));
-
-            if (streamInfo != null)
-            {
-                StreamReader sr = new StreamReader(streamInfo.Stream);
-                //This will Read Keys Collection for the xml file
-                XDocument document = XDocument.Parse(sr.ReadToEnd());
-
-                LoadPluginFeatures(document);
-
-                var preferences = from results in document.Descendants()
-                                  where results.Name.LocalName == "preference"
-                                  select new
-                                  {
-                                      name = (string)results.Attribute("name"),
-                                      value = (string)results.Attribute("value")
-                                  };
-
-                foreach (var pref in preferences)
-                {
-                    Preferences[pref.name.ToLowerInvariant()] = pref.value;
-                }
-
-                var accessList = from results in document.Descendants()
-                                 where results.Name.LocalName == "access"
-                                 select new
-                                 {
-                                     origin = (string)results.Attribute("origin"),
-                                     subdomains = (string)results.Attribute("subdomains") == "true"
-                                 };
-
-                foreach (var accessElem in accessList)
-                {
-                    AddWhiteListEntry(accessElem.origin, accessElem.subdomains);
-                }
-
-                var contentsTag = (from results in document.Descendants()
-                                  where results.Name.LocalName == "content"
-                                  select results).FirstOrDefault();
-
-                if (contentsTag != null)
-                {
-                    var src = contentsTag.Attribute("src");
-                    ContentSrc = (string)src.Value;
-                }
-            }
-            else
-            {
-                // no config.xml, allow all
-                AllowAllDomains = true;
-                AllowAllPlugins = true;
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/ConsoleHelper.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/ConsoleHelper.cs b/wp7/template/cordovalib/ConsoleHelper.cs
deleted file mode 100644
index c7bc8df..0000000
--- a/wp7/template/cordovalib/ConsoleHelper.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using Microsoft.Phone.Controls;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Text;
-
-namespace WPCordovaClassLib.CordovaLib
-{
-    class ConsoleHelper : IBrowserDecorator
-    {
-
-        public WebBrowser Browser { get; set; }
-
-        public void InjectScript() 
-        {
-            string script = @"(function(win) {
-        function exec(msg) { window.external.Notify('ConsoleLog/' + msg); }
-        var cons = win.console = win.console || {};
-        cons.log = exec;
-        cons.debug = cons.debug || cons.log;
-        cons.info = cons.info   || function(msg) { exec('INFO:' + msg ); };     
-        cons.warn = cons.warn   || function(msg) { exec('WARN:' + msg ); };
-        cons.error = cons.error || function(msg) { exec('ERROR:' + msg ); };
-    })(window);";
-
-           Browser.InvokeScript("execScript", new string[] { script });
-        }
-
-        public bool HandleCommand(string commandStr)
-        {
-            Debug.WriteLine(commandStr.Substring("ConsoleLog/".Length));
-            return true;
-        }
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/CordovaCommandCall.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/CordovaCommandCall.cs b/wp7/template/cordovalib/CordovaCommandCall.cs
deleted file mode 100644
index 7b9ee0c..0000000
--- a/wp7/template/cordovalib/CordovaCommandCall.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Linq;
-using System.Collections.Generic;
-
-namespace WPCordovaClassLib.Cordova
-{
-    /// <summary>
-    /// Represents Cordova native command call: action callback, etc
-    /// </summary>
-    public class CordovaCommandCall
-    {
-        public String Service { get; private set; }
-        public String Action { get; private set; }
-        public String CallbackId { get; private set; }
-        public String Args { get; private set; }
-        public String Namespace { get; set; }
-
-        /// <summary>
-        /// Retrieves command call parameters and creates wrapper for them
-        /// </summary>
-        /// <param name="commandStr">Command string in the form 'service/action/callback/args'</param>
-        /// <returns>New class instance or null of string does not represent Cordova command</returns>
-        public static CordovaCommandCall Parse(string commandStr)
-        {
-            //System.Diagnostics.Debug.WriteLine("CommandString : " + commandStr);
-            if (string.IsNullOrEmpty(commandStr))
-            {
-                return null;
-            }
-
-            string[] split = commandStr.Split('/');
-            if (split.Length < 3)
-            {
-                return null;
-            }
-
-            CordovaCommandCall commandCallParameters = new CordovaCommandCall();
-            commandCallParameters.Service = split[0];
-            commandCallParameters.Action = split[1];
-            commandCallParameters.CallbackId = split[2];
-            commandCallParameters.Namespace = String.Empty; 
-
-            try
-            {
-                string arg = split.Length <= 3 ? "[]" : String.Join("/", split.Skip(3));
-                if (!arg.StartsWith("[")) // save the exception
-                {
-                    arg = string.Format("[{0}]", arg);
-                }
-                List<string> args = JSON.JsonHelper.Deserialize<List<string>>(arg);
-                args.Add(commandCallParameters.CallbackId);
-                commandCallParameters.Args = JSON.JsonHelper.Serialize(args.ToArray());
-            }
-            catch (Exception)
-            {
-                return null;
-            }
-            // sanity check for illegal names
-            // was failing with ::
-            // CordovaCommandResult :: 1, Device1, {"status":1,"message":"{\"name\":\"XD.....
-            if (commandCallParameters.Service.IndexOfAny(new char[] { '@', ':', ',', '!', ' ' }) > -1)
-            {
-                return null;
-            }
-
-            return commandCallParameters;
-        }
-
-
-        /// <summary>
-        /// Private ctr to disable class creation.
-        /// New class instance must be initialized via CordovaCommandCall.Parse static method.
-        /// </summary>
-        private CordovaCommandCall() { }
-
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/CordovaView.xaml
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/CordovaView.xaml b/wp7/template/cordovalib/CordovaView.xaml
deleted file mode 100644
index b993d97..0000000
--- a/wp7/template/cordovalib/CordovaView.xaml
+++ /dev/null
@@ -1,65 +0,0 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements.  See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership.  The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License.  You may obtain a copy of the License at
-
-   http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied.  See the License for the
- specific language governing permissions and limitations
- under the License.  
--->
-<UserControl x:Class="WPCordovaClassLib.CordovaView"
-    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
-    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
-    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
-    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
-    mc:Ignorable="d"
-    FontFamily="{StaticResource PhoneFontFamilyNormal}"
-    FontSize="{StaticResource PhoneFontSizeNormal}"
-    Foreground="{StaticResource PhoneForegroundBrush}"
-    d:DesignHeight="480" d:DesignWidth="480" 
-    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone">
-    
-    <Grid x:Name="LayoutRoot" Background="Transparent">
-        
-        <phone:WebBrowser x:Name="CordovaBrowser" 
-                          Opacity="0"
-                          HorizontalAlignment="Stretch"  
-                          VerticalAlignment="Stretch" 
-                          IsScriptEnabled="True" 
-                          Foreground="White"
-                          Background="Black"
-                          Navigated="GapBrowser_Navigated" 
-                          Loaded="GapBrowser_Loaded" 
-                          Unloaded="GapBrowser_Unloaded" 
-                          ScriptNotify="GapBrowser_ScriptNotify" 
-                          LoadCompleted="GapBrowser_LoadCompleted" 
-                          Navigating="GapBrowser_Navigating" 
-                          NavigationFailed="GapBrowser_NavigationFailed" 
-                          IsGeolocationEnabled="True">
-            <phone:WebBrowser.Projection>
-                <PlaneProjection x:Name="BrowserProjector" CenterOfRotationX="0" RotationY="-180"/>
-            </phone:WebBrowser.Projection>
-            <phone:WebBrowser.Resources>
-                <Storyboard x:Name="RotateIn" BeginTime="0:0:0.5">
-                    <DoubleAnimation
-                        Storyboard.TargetName="BrowserProjector"
-                        Storyboard.TargetProperty="RotationY"
-                        To="0" Duration="0:0:0.6"/>
-                </Storyboard>
-            </phone:WebBrowser.Resources>
-
-        </phone:WebBrowser>
-        
-    </Grid>
-</UserControl>
-
-    

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/CordovaView.xaml.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/CordovaView.xaml.cs b/wp7/template/cordovalib/CordovaView.xaml.cs
deleted file mode 100644
index f7d026f..0000000
--- a/wp7/template/cordovalib/CordovaView.xaml.cs
+++ /dev/null
@@ -1,561 +0,0 @@
-/*
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-*/
-
-using Microsoft.Phone.Controls;
-using Microsoft.Phone.Shell;
-using System;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.Globalization;
-using System.IO;
-using System.IO.IsolatedStorage;
-using System.Linq;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Resources;
-using System.Xml.Linq;
-using WPCordovaClassLib.Cordova;
-using WPCordovaClassLib.Cordova.JSON;
-using WPCordovaClassLib.CordovaLib;
-
-
-
-namespace WPCordovaClassLib
-{
-    public partial class CordovaView : UserControl
-    {
-
-        /// <summary>
-        /// Indicates whether web control has been loaded and no additional initialization is needed.
-        /// Prevents data clearing during page transitions.
-        /// </summary>
-        private bool IsBrowserInitialized = false;
-
-        /// <summary>
-        /// Set when the user attaches a back button handler inside the WebBrowser
-        /// </summary>
-        private bool OverrideBackButton = false;
-
-        /// <summary>
-        /// Sentinel to keep track of page changes as a result of the hardware back button
-        /// Set to false when the back-button is pressed, which calls js window.history.back()
-        /// If the page changes as a result of the back button the event is cancelled.
-        /// </summary>
-        private bool PageDidChange = false;
-
-        private static string AppRoot = "/app/";
-
-
-        /// <summary>
-        /// Handles native api calls
-        /// </summary>
-        private NativeExecution nativeExecution;
-
-        protected BrowserMouseHelper bmHelper;
-
-        private ConfigHandler configHandler;
-
-        private Dictionary<string, IBrowserDecorator> browserDecorators;
-
-        public System.Windows.Controls.Grid _LayoutRoot
-        {
-            get
-            {
-                return ((System.Windows.Controls.Grid)(this.FindName("LayoutRoot")));
-            }
-        }
-
-        public WebBrowser Browser
-        {
-            get
-            {
-                return CordovaBrowser;
-            }
-        }
-
-        /*
-         * Setting StartPageUri only has an effect if called before the view is loaded.
-         **/
-        protected Uri _startPageUri = null;
-        public Uri StartPageUri
-        {
-            get
-            {
-                if (_startPageUri == null)
-                {
-                    // default
-                    return new Uri(AppRoot + "www/index.html", UriKind.Relative);
-                }
-                else
-                {
-                    return _startPageUri;
-                }
-            }
-            set
-            {
-                if (!this.IsBrowserInitialized)
-                {
-                    _startPageUri = value;
-                }
-            }
-        }
-
-        public CordovaView()
-        {
-
-            InitializeComponent();
-
-            if (DesignerProperties.IsInDesignTool)
-            {
-                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
-            {
-
-            }
-
-            configHandler = new ConfigHandler();
-            configHandler.LoadAppPackageConfig();
-
-            if (configHandler.ContentSrc != null)
-            {
-                if (Uri.IsWellFormedUriString(configHandler.ContentSrc, UriKind.Absolute))
-                {
-                    this.StartPageUri = new Uri(configHandler.ContentSrc, UriKind.Absolute);
-                }
-                else
-                {
-                    this.StartPageUri = new Uri(AppRoot + "www/" + configHandler.ContentSrc, UriKind.Relative);
-                }
-            }
-
-            ApplyConfigurationPreferences();
-
-            browserDecorators = new Dictionary<string, IBrowserDecorator>();
-
-            // initializes native execution logic
-            nativeExecution = new NativeExecution(ref this.CordovaBrowser);
-            bmHelper = new BrowserMouseHelper(ref this.CordovaBrowser);
-
-            CreateDecorators();
-        }
-
-        /*
-         *   browserDecorators are a collection of plugin-like classes (IBrowserDecorator) that add some bit of functionality to the browser.
-         *   These are somewhat different than plugins in that they are usually not async and patch a browser feature that we would
-         *   already expect to have.  Essentially these are browser polyfills that are patched from the outside in.
-         * */
-        void CreateDecorators()
-        {
-            XHRHelper xhrProxy = new XHRHelper();
-            xhrProxy.Browser = CordovaBrowser;
-            browserDecorators.Add("XHRLOCAL", xhrProxy);
-
-            OrientationHelper orientHelper = new OrientationHelper();
-            orientHelper.Browser = CordovaBrowser;
-            browserDecorators.Add("Orientation", orientHelper);
-
-            DOMStorageHelper storageHelper = new DOMStorageHelper();
-            storageHelper.Browser = CordovaBrowser;
-            browserDecorators.Add("DOMStorage", storageHelper);
-
-            ConsoleHelper console = new ConsoleHelper();
-            console.Browser = CordovaBrowser;
-            browserDecorators.Add("ConsoleLog", console);
-
-        }
-
-        /// <summary>
-        /// Applies configuration preferences. Only BackgroundColor+fullscreen is currently supported.
-        /// </summary>
-        private void ApplyConfigurationPreferences()
-        {
-            string bgColor = configHandler.GetPreference("backgroundcolor");
-
-            if (!String.IsNullOrEmpty(bgColor)) {
-                try
-                {
-                    Browser.Background = new SolidColorBrush(ColorFromHex(bgColor));
-                }
-                catch (Exception ex)
-                {
-                    Debug.WriteLine("Unable to parse BackgroundColor value '{0}'. Error: {1}", bgColor, ex.Message);
-                }
-            }
-
-        }
-
-
-
-        void AppClosing(object sender, ClosingEventArgs e)
-        {
-            //Debug.WriteLine("AppClosing");
-        }
-
-        void AppDeactivated(object sender, DeactivatedEventArgs e)
-        {
-            Debug.WriteLine("INFO: AppDeactivated");
-
-            try
-            {
-                CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('pause');" });
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("ERROR: Pause event error");
-            }
-        }
-
-        void AppLaunching(object sender, LaunchingEventArgs e)
-        {
-            //Debug.WriteLine("INFO: AppLaunching");
-        }
-
-        void AppActivated(object sender, Microsoft.Phone.Shell.ActivatedEventArgs e)
-        {
-            Debug.WriteLine("INFO: AppActivated");
-            try
-            {
-                CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('resume');" });
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("ERROR: Resume event error");
-            }
-        }
-
-        void GapBrowser_Loaded(object sender, RoutedEventArgs e)
-        {
-            if (DesignerProperties.IsInDesignTool)
-            {
-                return;
-            }
-
-            // prevents refreshing web control to initial state during pages transitions
-            if (this.IsBrowserInitialized) return;
-
-            try
-            {
-
-                // Before we possibly clean the ISO-Store, we need to grab our generated UUID, so we can rewrite it after.
-                string deviceUUID = "";
-
-                using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
-                {
-                    try
-                    {
-                        IsolatedStorageFileStream fileStream = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Open, FileAccess.Read, appStorage);
-
-                        using (StreamReader reader = new StreamReader(fileStream))
-                        {
-                            deviceUUID = reader.ReadLine();
-                        }
-                    }
-                    catch (Exception /*ex*/)
-                    {
-                        deviceUUID = Guid.NewGuid().ToString();
-                        Debug.WriteLine("Updating IsolatedStorage for APP:DeviceID :: " + deviceUUID);
-                        IsolatedStorageFileStream file = new IsolatedStorageFileStream("DeviceID.txt", FileMode.Create, FileAccess.Write, appStorage);
-                        using (StreamWriter writeFile = new StreamWriter(file))
-                        {
-                            writeFile.WriteLine(deviceUUID);
-                            writeFile.Close();
-                        }
-                    }
-                }
-
-                StreamResourceInfo streamInfo = Application.GetResourceStream(new Uri("CordovaSourceDictionary.xml", UriKind.Relative));
-
-                if (streamInfo != null)
-                {
-                    StreamReader sr = new StreamReader(streamInfo.Stream);
-                    //This will Read Keys Collection for the xml file
-
-                    XDocument document = XDocument.Parse(sr.ReadToEnd());
-
-                    var files = from results in document.Descendants("FilePath")
-                                select new
-                                {
-                                    path = (string)results.Attribute("Value")
-                                };
-                    StreamResourceInfo fileResourceStreamInfo;
-
-                    using (IsolatedStorageFile appStorage = IsolatedStorageFile.GetUserStoreForApplication())
-                    {
-
-                        foreach (var file in files)
-                        {
-                            fileResourceStreamInfo = Application.GetResourceStream(new Uri(file.path, UriKind.Relative));
-
-                            if (fileResourceStreamInfo != null)
-                            {
-                                using (BinaryReader br = new BinaryReader(fileResourceStreamInfo.Stream))
-                                {
-                                    byte[] data = br.ReadBytes((int)fileResourceStreamInfo.Stream.Length);
-
-                                    string strBaseDir = AppRoot + file.path.Substring(0, file.path.LastIndexOf(System.IO.Path.DirectorySeparatorChar));
-
-                                    if (!appStorage.DirectoryExists(strBaseDir))
-                                    {
-                                        Debug.WriteLine("INFO: Creating Directory :: " + strBaseDir);
-                                        appStorage.CreateDirectory(strBaseDir);
-                                    }
-
-                                    // This will truncate/overwrite an existing file, or
-                                    using (IsolatedStorageFileStream outFile = appStorage.OpenFile(AppRoot + file.path, FileMode.Create))
-                                    {
-                                        Debug.WriteLine("INFO: Writing data for " + AppRoot + file.path + " and length = " + data.Length);
-                                        using (var writer = new BinaryWriter(outFile))
-                                        {
-                                            writer.Write(data);
-                                        }
-                                    }
-                                }
-                            }
-                            else
-                            {
-                                Debug.WriteLine("ERROR: Failed to write file :: " + file.path + " did you forget to add it to the project?");
-                            }
-                        }
-                    }
-                }
-
-                CordovaBrowser.Navigate(StartPageUri);
-                IsBrowserInitialized = true;
-                AttachHardwareButtonHandlers();
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine("ERROR: Exception in GapBrowser_Loaded :: {0}", ex.Message);
-            }
-        }
-
-        void AttachHardwareButtonHandlers()
-        {
-            PhoneApplicationFrame frame = Application.Current.RootVisual as PhoneApplicationFrame;
-            if (frame != null)
-            {
-                PhoneApplicationPage page = frame.Content as PhoneApplicationPage;
-
-                if (page != null)
-                {
-                    page.BackKeyPress += new EventHandler<CancelEventArgs>(page_BackKeyPress);
-                    // CB-2347 -jm
-                    string fullscreen = configHandler.GetPreference("fullscreen");
-                    bool bFullScreen = false;
-                    if (bool.TryParse(fullscreen, out bFullScreen) && bFullScreen)
-                    {
-                        SystemTray.SetIsVisible(page, false);
-                    }
-                }
-            }
-        }
-
-        void page_BackKeyPress(object sender, CancelEventArgs e)
-        {
-
-            if (OverrideBackButton)
-            {
-                try
-                {
-                    CordovaBrowser.InvokeScript("eval", new string[] { "cordova.fireDocumentEvent('backbutton', {}, true);" });
-                    e.Cancel = true;
-                }
-                catch (Exception ex)
-                {
-                    Debug.WriteLine("Exception while invoking backbutton into cordova view: " + ex.Message);
-                }
-            }
-            else
-            {
-                try
-                {
-                    PageDidChange = false;
-
-                    Uri uriBefore = this.Browser.Source;
-                    // calling js history.back with result in a page change if history was valid.
-                    CordovaBrowser.InvokeScript("eval", new string[] { "(function(){window.history.back();})()" });
-
-                    Uri uriAfter = this.Browser.Source;
-
-                    e.Cancel = PageDidChange || (uriBefore != uriAfter);
-                }
-                catch (Exception)
-                {
-                    e.Cancel = false; // exit the app ... ?
-                }
-            }
-        }
-
-        void GapBrowser_LoadCompleted(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            string nativeReady = "(function(){ window.setTimeout(function(){cordova.require('cordova/channel').onNativeReady.fire()},0) })();";
-
-            try
-            {
-                CordovaBrowser.InvokeScript("execScript", new string[] { nativeReady });
-            }
-            catch (Exception)
-            {
-                Debug.WriteLine("Error calling js to fire nativeReady event. Did you include cordova.js in your html script tag?");
-            }
-
-            if (this.CordovaBrowser.Opacity < 1)
-            {
-                this.CordovaBrowser.Opacity = 1;
-                RotateIn.Begin();
-            }
-        }
-
-
-        void GapBrowser_Navigating(object sender, NavigatingEventArgs e)
-        {
-            if (!configHandler.URLIsAllowed(e.Uri.ToString()))
-            {
-                e.Cancel = true;
-                return;
-            }
-
-            this.PageDidChange = true;
-            // Debug.WriteLine("GapBrowser_Navigating to :: " + e.Uri.ToString());
-            this.nativeExecution.ResetAllCommands();
-
-            // TODO: check whitelist / blacklist
-            // NOTE: Navigation can be cancelled by setting :        e.Cancel = true;
-        }
-
-        /*
-         *  This method does the work of routing commands
-         *  NotifyEventArgs.Value contains a string passed from JS
-         *  If the command already exists in our map, we will just attempt to call the method(action) specified, and pass the args along
-         *  Otherwise, we create a new instance of the command, add it to the map, and call it ...
-         *  This method may also receive JS error messages caught by window.onerror, in any case where the commandStr does not appear to be a valid command
-         *  it is simply output to the debugger output, and the method returns.
-         *
-         **/
-        void GapBrowser_ScriptNotify(object sender, NotifyEventArgs e)
-        {
-            string commandStr = e.Value;
-            string commandName = commandStr.Split('/').FirstOrDefault();
-
-            if (browserDecorators.ContainsKey(commandName))
-            {
-                browserDecorators[commandName].HandleCommand(commandStr);
-                return;
-            }
-
-            CordovaCommandCall commandCallParams = CordovaCommandCall.Parse(commandStr);
-
-            if (commandCallParams == null)
-            {
-                // ERROR
-                Debug.WriteLine("ScriptNotify :: " + commandStr);
-            }
-            else if (commandCallParams.Service == "CoreEvents")
-            {
-                switch (commandCallParams.Action.ToLower())
-                {
-                    case "overridebackbutton":
-                        string arg0 = JsonHelper.Deserialize<string[]>(commandCallParams.Args)[0];
-                        this.OverrideBackButton = (arg0 != null && arg0.Length > 0 && arg0.ToLower() == "true");
-                        break;
-                }
-            }
-            else
-            {
-                if (configHandler.IsPluginAllowed(commandCallParams.Service))
-                {
-                    nativeExecution.ProcessCommand(commandCallParams);
-                }
-                else
-                {
-                    Debug.WriteLine("Error::Plugin not allowed in config.xml. " + commandCallParams.Service);
-                }
-            }
-        }
-
-        public void LoadPage(string url)
-        {
-            try
-            {
-                Uri newLoc = new Uri(url, UriKind.RelativeOrAbsolute);
-                CordovaBrowser.Navigate(newLoc);
-            }
-            catch (Exception)
-            {
-
-            }
-        }
-
-        private void GapBrowser_Unloaded(object sender, RoutedEventArgs e)
-        {
-
-        }
-
-        private void GapBrowser_NavigationFailed(object sender, System.Windows.Navigation.NavigationFailedEventArgs e)
-        {
-            Debug.WriteLine("GapBrowser_NavigationFailed :: " + e.Uri.ToString());
-        }
-
-        private void GapBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
-        {
-            Debug.WriteLine("GapBrowser_Navigated :: " + e.Uri.ToString());
-            foreach (IBrowserDecorator iBD in browserDecorators.Values)
-            {
-                iBD.InjectScript();
-            }
-        }
-
-        /// <summary>
-        /// Converts hex color string to a new System.Windows.Media.Color structure.
-        /// If the hex is only rgb, it will be full opacity.
-        /// </summary>
-        protected Color ColorFromHex(string hexString)
-        {
-            string cleanHex = hexString.Replace("#", "").Replace("0x", "");
-            // turn #FFF into #FFFFFF
-            if (cleanHex.Length == 3)
-            {
-                cleanHex = "" + cleanHex[0] + cleanHex[0] + cleanHex[1] + cleanHex[1] + cleanHex[2] + cleanHex[2];
-            }
-            // add an alpha 100% if it is missing
-            if (cleanHex.Length == 6)
-            {
-                cleanHex = "FF" + cleanHex;
-            }
-            int argb = Int32.Parse(cleanHex, NumberStyles.HexNumber);
-            Color clr = Color.FromArgb((byte)((argb & 0xff000000) >> 0x18),
-                              (byte)((argb & 0xff0000) >> 0x10),
-                              (byte)((argb & 0xff00) >> 8),
-                              (byte)(argb & 0xff));
-            return clr;
-        }
-
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/DOMStorageHelper.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/DOMStorageHelper.cs b/wp7/template/cordovalib/DOMStorageHelper.cs
deleted file mode 100644
index 5f16c78..0000000
--- a/wp7/template/cordovalib/DOMStorageHelper.cs
+++ /dev/null
@@ -1,277 +0,0 @@
-/*  
-    Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-    
-    http://www.apache.org/licenses/LICENSE-2.0
-    
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.IO.IsolatedStorage;
-using System.Collections.Generic;
-using Microsoft.Phone.Controls;
-using System.Linq;
-using WPCordovaClassLib.Cordova.JSON;
-using WPCordovaClassLib.CordovaLib;
-
-/*
- * Translates DOMStorage API between JS and Isolated Storage
- * Missing pieces : QUOTA_EXCEEDED_ERR  + StorageEvent  
- * */
-
-namespace WPCordovaClassLib
-{
-    public class DOMStorageHelper : IBrowserDecorator
-    {
-        public WebBrowser Browser { get; set; }
-        public DOMStorageHelper()
-        {
-            // always clear session at creation
-            UserSettings["sessionStorage"] = new Dictionary<string, string>();
-
-            if (!UserSettings.Contains("localStorage"))
-            {
-                UserSettings["localStorage"] = new Dictionary<string, string>();
-                UserSettings.Save();
-            }
-            Application.Current.Exit += new EventHandler(OnAppExit);
-        }
-
-        void OnAppExit(object sender, EventArgs e)
-        {
-            UserSettings.Remove("sessionStorage");
-            UserSettings.Save();
-        }
-
-        protected IsolatedStorageSettings UserSettings
-        {
-            get
-            {
-                return IsolatedStorageSettings.ApplicationSettings;
-            }
-        }
-
-        protected Dictionary<string, string> getStorageByType(string type)
-        {
-            if (!UserSettings.Contains(type))
-            {
-                UserSettings[type] = new Dictionary<string, string>();
-                UserSettings.Save();
-            }
-            return UserSettings[type] as Dictionary<string, string>;
-        }
-
-        public void InjectScript()
-        {
-            string script = @"(function(win, doc) {
-var docDomain = null;
-try {
-    docDomain = doc.domain;
-} catch (err) {}
-if (!docDomain || docDomain.length === 0) {
-    var DOMStorage = function(type) {
-        if (type == 'sessionStorage') {
-            this._type = type;
-        }
-        Object.defineProperty(this, 'length', {
-            configurable: true,
-            get: function() {
-                return this.getLength();
-            }
-        });
-    };
-    DOMStorage.prototype = {
-        _type: 'localStorage',
-        _result: null,
-        keys: null,
-        onResult: function(key, valueStr) {
-            if (!this.keys) {
-                this.keys = [];
-            }
-            this._result = valueStr;
-        },
-        onKeysChanged: function(jsonKeys) {
-            this.keys = JSON.parse(jsonKeys);
-            var key;
-            for (var n = 0, len = this.keys.length; n < len; n++) {
-                key = this.keys[n];
-                if (!this.hasOwnProperty(key)) {
-                    Object.defineProperty(this, key, {
-                        configurable: true,
-                        get: function() {
-                            return this.getItem(key);
-                        },
-                        set: function(val) {
-                            return this.setItem(key, val);
-                        }
-                    });
-                }
-            }
-        },
-        initialize: function() {
-            window.external.Notify('DOMStorage/' + this._type + '/load/keys');
-        },
-        getLength: function() {
-            if (!this.keys) {
-                this.initialize();
-            }
-            return this.keys.length;
-        },
-        key: function(n) {
-            if (!this.keys) {
-                this.initialize();
-            }
-            if (n >= this.keys.length) {
-                return null;
-            } else {
-                return this.keys[n];
-            }
-        },
-        getItem: function(key) {
-            if (!this.keys) {
-                this.initialize();
-            }
-            var retVal = null;
-            if (this.keys.indexOf(key) > -1) {
-                window.external.Notify('DOMStorage/' + this._type + '/get/' + key);
-                retVal = this._result;
-                if(retVal) {
-                    retVal =  window.unescape(decodeURIComponent(retVal));            
-                }
-                else {
-                   window.external.Notify('DOMStorage/' + this._type + '/remove/' + key);
-                   delete this[key];
-                }
-                this._result = null;
-            }
-            return retVal;
-        },
-        setItem: function(key, value) {
-            if (!this.keys) {
-                this.initialize();
-            }
-            window.external.Notify('DOMStorage/' + this._type + '/set/' + key + '/' + encodeURIComponent(window.escape(value)));
-        },
-        removeItem: function(key) {
-            if (!this.keys) {
-                this.initialize();
-            }
-            var index = this.keys.indexOf(key);
-            if (index > -1) {
-                this.keys.splice(index, 1);
-                window.external.Notify('DOMStorage/' + this._type + '/remove/' + key);
-                delete this[key];
-            }
-        },
-        clear: function() {
-            if (!this.keys) {
-                this.initialize();
-            }
-            for (var n = 0, len = this.keys.length; n < len; n++) {
-                delete this[this.keys[n]];
-            }
-            this.keys = [];
-            window.external.Notify('DOMStorage/' + this._type + '/clear/');
-        }
-    };
-    if (typeof window.localStorage === 'undefined') {
-        Object.defineProperty(window, 'localStorage', {
-            writable: false,
-            configurable: false,
-            value: new DOMStorage('localStorage')
-        });
-        window.localStorage.initialize();
-    }
-    if (typeof window.sessionStorage === 'undefined') {
-        Object.defineProperty(window, 'sessionStorage', {
-            writable: false,
-            configurable: false,
-            value: new DOMStorage('sessionStorage')
-        });
-        window.sessionStorage.initialize();
-    }
-}
-})(window, document);";
-
-            Browser.InvokeScript("execScript", new string[] { script });
-        }
- 
-        public bool HandleCommand(string commandStr)
-        {
-            string[] split = commandStr.Split('/');
-            if (split.Length > 3)
-            {
-                string api = split[0];
-                string type = split[1]; // localStorage || sessionStorage
-                string command = split[2];
-                string param = split[3];
-
-                Dictionary<string, string> currentStorage = getStorageByType(type);
-
-                switch (command)
-                {
-                    case "get":
-                        {
-
-                            if (currentStorage.Keys.Contains(param))
-                            {
-                                string value = currentStorage[param];
-                                Browser.InvokeScript("execScript", "window." + type + ".onResult('" + param + "','" + value + "');");
-                            }
-                            else
-                            {
-                                Browser.InvokeScript("execScript", "window." + type + ".onResult('" + param + "');");
-                            }
-
-                        }
-                        break;
-                    case "load":
-                        {
-                            string[] keys = currentStorage.Keys.ToArray();
-                            string jsonString = JsonHelper.Serialize(keys);
-                            string callbackJS = "window." + type + ".onKeysChanged('" + jsonString + "');";
-                            Browser.InvokeScript("execScript", callbackJS);
-                        }
-                        break;
-                    case "set":
-                        {
-                            // TODO: check that length is not out of bounds
-                            currentStorage[param] = split[4];
-                            UserSettings.Save();
-                            string[] keys = currentStorage.Keys.ToArray();
-                            string jsonString = JsonHelper.Serialize(keys);
-                            string callbackJS = "window." + type + ".onKeysChanged('" + jsonString + "');";
-                            Browser.InvokeScript("execScript", callbackJS);
-                        }
-                        break;
-                    case "remove":
-                        currentStorage.Remove(param);
-                        UserSettings.Save();
-                        break;
-                    case "clear":
-                        currentStorage = new Dictionary<string, string>();
-                        UserSettings[type] = currentStorage;
-                        UserSettings.Save();
-                        break;
-                }
-
-            }
-            return true;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/IBrowserDecorator.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/IBrowserDecorator.cs b/wp7/template/cordovalib/IBrowserDecorator.cs
deleted file mode 100644
index 14ea815..0000000
--- a/wp7/template/cordovalib/IBrowserDecorator.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using Microsoft.Phone.Controls;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-
-namespace WPCordovaClassLib.CordovaLib
-{
-    interface IBrowserDecorator
-    {
-        WebBrowser Browser { get; set; }
-        void InjectScript();
-        bool HandleCommand(string cmd);
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/ImageExifHelper.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/ImageExifHelper.cs b/wp7/template/cordovalib/ImageExifHelper.cs
deleted file mode 100644
index 62b6462..0000000
--- a/wp7/template/cordovalib/ImageExifHelper.cs
+++ /dev/null
@@ -1,209 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
- 
-*/
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Windows.Media.Imaging;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    public class ImageExifOrientation
-    {
-        public const int Portrait = 1;
-        public const int PortraitUpsideDown = 3;
-        public const int LandscapeLeft = 6;
-        public const int LandscapeRight = 8;
-    }
-
-    public class ImageExifHelper
-    {
-
-        public static Stream RotateStream(Stream stream, int angle)
-        {
-            stream.Position = 0;
-            if (angle % 90 != 0 || angle < 0)
-            {
-                throw new ArgumentException();
-            }
-            if (angle % 360 == 0)
-            {
-                return stream;
-            }
-
-            angle = angle % 360;
-
-            BitmapImage bitmap = new BitmapImage();
-            bitmap.SetSource(stream);
-            WriteableBitmap wbSource = new WriteableBitmap(bitmap);
-
-            WriteableBitmap wbTarget = null;
-
-            int srcPixelWidth = wbSource.PixelWidth;
-            int srcPixelHeight = wbSource.PixelHeight;
-
-            if (angle % 180 == 0)
-            {
-                wbTarget = new WriteableBitmap(srcPixelWidth, srcPixelHeight);
-            }
-            else
-            {
-                wbTarget = new WriteableBitmap(srcPixelHeight, srcPixelWidth);
-            }
-
-            int destPixelWidth = wbTarget.PixelWidth;
-            int[] srcPxls = wbSource.Pixels;
-            int[] destPxls = wbTarget.Pixels;
-
-            // this ugly if/else is to avoid a conditional check for every pixel
-            if (angle == 90)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[(srcPixelHeight - y - 1) + (x * destPixelWidth)] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-            else if (angle == 180)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[(srcPixelWidth - x - 1) + (srcPixelHeight - y - 1) * srcPixelWidth] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-            else if (angle == 270)
-            {
-                for (int x = 0; x < srcPixelWidth; x++)
-                {
-                    for (int y = 0; y < srcPixelHeight; y++)
-                    {
-                        destPxls[y + (srcPixelWidth - x - 1) * destPixelWidth] = srcPxls[x + y * srcPixelWidth];
-                    }
-                }
-            }
-
-            MemoryStream targetStream = new MemoryStream();
-            wbTarget.SaveJpeg(targetStream, destPixelWidth, wbTarget.PixelHeight, 0, 100);
-            return targetStream;
-        }
-
-        public static int getImageOrientationFromStream(Stream imgStream)
-        {
-
-            // 0xFFD8 : jpgHeader
-            // 0xFFE1 :
-            // 0x???? : length of exif data
-            // 0x????, 0x???? : Chars 'E','x','i','f'
-            // 0x0000 : 2 empty bytes
-            // <== mark beginning of tags SIZE:ID:VALUE
-            // 0x???? : 'II' or 'MM' for Intel or Motorola ( always getting II on my WP7 devices ), determines littleEndian-ness
-            // 0x002A : marker value
-            // 0x???? : offset to the Image File Data
-
-            // XXXX possible space before actual tag data ... we skip to mark + offset
-
-            // 0x???? number of exif tags present
-
-            // make sure we are at the beginning
-            imgStream.Seek(0, SeekOrigin.Begin);
-            BinaryReader reader = new BinaryReader(imgStream);
-
-            byte[] jpgHdr = reader.ReadBytes(2); // always (0xFFD8)
-
-            byte start = reader.ReadByte(); // 0xFF
-            byte index = reader.ReadByte(); // 0xE1
-
-            while (start == 0xFF && index != 0xE1) // This never seems to happen, todo: optimize
-            {
-                // Get the data length
-                ushort dLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-                // skip along
-                reader.ReadBytes(dLen - 2);
-                start = reader.ReadByte();
-                index = reader.ReadByte();
-            }
-
-            // It's only success if we found the 0xFFE1 marker
-            if (start != 0xFF || index != 0xE1)
-            {
-                //   throw new Exception("Could not find Exif data block");
-                Debug.WriteLine("Did not find EXIF data");
-                return 0;
-            }
-
-            // read 2 byte length of EXIF data
-            ushort exifLen = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            String exif = ""; // build the string
-            for (var n = 0; n < 4; n++)
-            {
-                exif += reader.ReadChar();
-            }
-            if (exif != "Exif")
-            {
-                // did not find exif data ...
-                Debug.WriteLine("Did not find EXIF data");
-                return 0;
-            }
-
-            // read 2 empty bytes
-            //ushort emptyBytes = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            reader.ReadBytes(2);
-
-            long headerMark = reader.BaseStream.Position; // where are we now <==
-
-            //bool isLEndian = (reader.ReadChar() + "" + reader.ReadChar()) == "II";
-            reader.ReadBytes(2); // 'II' or 'MM', but we don't care
-
-            if (0x002A != BitConverter.ToUInt16(reader.ReadBytes(2), 0))
-            {
-                Debug.WriteLine("Error in data != 0x002A");
-                return 0;
-            }
-
-            // Get the offset to the IFD (image file directory)
-            ushort imgOffset = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-
-            imgStream.Position = headerMark + imgOffset;
-            ushort tagCount = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-            for (ushort x = 0; x < tagCount; x++)
-            {
-                // Orientation = 0x112, aka 274
-                if (0x112 == BitConverter.ToUInt16(reader.ReadBytes(2), 0))
-                {
-                    ushort dType = BitConverter.ToUInt16(reader.ReadBytes(2), 0);
-                    // don't care ..
-                    uint comps = reader.ReadUInt32();
-                    byte[] tagData = reader.ReadBytes(4);
-                    int orientation = (int)tagData[0];
-                    Debug.WriteLine("orientation = " + orientation.ToString());
-                    return orientation;
-                    // 6 means rotate clockwise 90 deg
-                    // 8 means rotate counter-clockwise 90 deg
-                    // 1 means all is good
-                    // 3 means flip vertical
-                }
-                // skip to the next item, 12 bytes each
-                reader.BaseStream.Seek(10, SeekOrigin.Current);
-            }
-            return 0;
-        }
-
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/JSON/JsonHelper.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/JSON/JsonHelper.cs b/wp7/template/cordovalib/JSON/JsonHelper.cs
deleted file mode 100644
index 44511f6..0000000
--- a/wp7/template/cordovalib/JSON/JsonHelper.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Net;
-using System.Windows;
-using System.Windows.Controls;
-using System.Windows.Documents;
-using System.Windows.Ink;
-using System.Windows.Input;
-using System.Windows.Media;
-using System.Windows.Media.Animation;
-using System.Windows.Shapes;
-using System.Runtime.Serialization.Json;
-using System.IO;
-using System.Collections.Generic;
-using System.Text;
-using System.Diagnostics;
-
-namespace WPCordovaClassLib.Cordova.JSON
-{
-    /// <summary>
-    /// Provides JSON serialization/deserialization functionality.
-    /// </summary>
-    public static class JsonHelper
-    {
-        /// <summary>
-        /// Serializes object to JSON string representation
-        /// </summary>
-        /// <param name="obj">object to serialize</param>
-        /// <returns>JSON representation of the object. Returns 'null' string for null passed as argument</returns>
-        public static string Serialize(object obj)
-        {
-            if (obj == null)
-            {
-                return "null";
-            }
-
-            DataContractJsonSerializer ser = new DataContractJsonSerializer(obj.GetType());
-
-            MemoryStream ms = new MemoryStream();
-            ser.WriteObject(ms, obj);
-
-            ms.Position = 0;
-
-            string json = String.Empty;
-
-            using (StreamReader sr = new StreamReader(ms))
-            {
-                json = sr.ReadToEnd();
-            }
-
-            ms.Close();
-
-            return json;
-
-        }
-
-        /// <summary>
-        /// Parses json string to object instance
-        /// </summary>
-        /// <typeparam name="T">type of the object</typeparam>
-        /// <param name="json">json string representation of the object</param>
-        /// <returns>Deserialized object instance</returns>
-        public static T Deserialize<T>(string json)
-        {
-            DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(T));
-            object result = null;
-            try
-            {
-                using (MemoryStream mem = new MemoryStream(Encoding.UTF8.GetBytes(json)))
-                {
-                    result = deserializer.ReadObject(mem);
-                }
-            }
-            catch (Exception ex)
-            {
-                Debug.WriteLine(ex.Message);
-                Debug.WriteLine("Failed to deserialize " + typeof(T) + " with JSON value :: " + json);
-            }
-
-            return (T)result;
-
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/MimeTypeMapper.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/MimeTypeMapper.cs b/wp7/template/cordovalib/MimeTypeMapper.cs
deleted file mode 100644
index a2794f5..0000000
--- a/wp7/template/cordovalib/MimeTypeMapper.cs
+++ /dev/null
@@ -1,101 +0,0 @@
-/*  
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-	
-	http://www.apache.org/licenses/LICENSE-2.0
-	
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System.Collections.Generic;
-using System.IO;
-
-namespace WPCordovaClassLib.Cordova.Commands
-{
-    /// <summary>
-    /// Represents file extension to mime type mapper.
-    /// </summary>
-    public static class MimeTypeMapper
-    {
-        /// <summary>
-        /// For unknown type it is recommended to use 'application/octet-stream'
-        /// http://stackoverflow.com/questions/1176022/unknown-file-type-mime
-        /// </summary>
-        private static string DefaultMimeType = "application/octet-stream";
-
-        /// <summary>
-        /// Stores mime type for all necessary extension
-        /// </summary>
-        private static readonly Dictionary<string, string> MIMETypesDictionary = new Dictionary<string, string>
-                                                                             {                                                                                
-                                                                                 {"avi", "video/x-msvideo"},
-                                                                                 {"bmp", "image/bmp"},                                                                                                                                                                
-                                                                                 {"gif", "image/gif"},
-                                                                                 {"html","text/html"},                                                                              
-                                                                                 {"jpe", "image/jpeg"},
-                                                                                 {"jpeg", "image/jpeg"},
-                                                                                 {"jpg", "image/jpeg"},     
-                                                                                 {"js","text/javascript"},                                                                         
-                                                                                 {"mov", "video/quicktime"},
-                                                                                 {"mp2", "audio/mpeg"},
-                                                                                 {"mp3", "audio/mpeg"},
-                                                                                 {"mp4", "video/mp4"},
-                                                                                 {"mpe", "video/mpeg"},
-                                                                                 {"mpeg", "video/mpeg"},
-                                                                                 {"mpg", "video/mpeg"},
-                                                                                 {"mpga", "audio/mpeg"},                                                                                
-                                                                                 {"pbm", "image/x-portable-bitmap"},
-                                                                                 {"pcm", "audio/x-pcm"},
-                                                                                 {"pct", "image/pict"},
-                                                                                 {"pgm", "image/x-portable-graymap"},
-                                                                                 {"pic", "image/pict"},
-                                                                                 {"pict", "image/pict"},
-                                                                                 {"png", "image/png"},
-                                                                                 {"pnm", "image/x-portable-anymap"},
-                                                                                 {"pnt", "image/x-macpaint"},
-                                                                                 {"pntg", "image/x-macpaint"},
-                                                                                 {"ppm", "image/x-portable-pixmap"},
-                                                                                 {"qt", "video/quicktime"},
-                                                                                 {"ra", "audio/x-pn-realaudio"},
-                                                                                 {"ram", "audio/x-pn-realaudio"},
-                                                                                 {"ras", "image/x-cmu-raster"},
-                                                                                 {"rgb", "image/x-rgb"},
-                                                                                 {"snd", "audio/basic"},
-                                                                                 {"txt", "text/plain"},
-                                                                                 {"tif", "image/tiff"},
-                                                                                 {"tiff", "image/tiff"},
-                                                                                 {"wav", "audio/x-wav"},
-                                                                                 {"wbmp", "image/vnd.wap.wbmp"},
-
-                                                                             };
-        /// <summary>
-        /// Gets mime type by file extension
-        /// </summary>
-        /// <param name="fileName">file name to extract extension</param>
-        /// <returns>mime type</returns>
-        public static string GetMimeType(string fileName)
-        {
-            string ext = Path.GetExtension(fileName);
-
-            // invalid extension
-            if (string.IsNullOrEmpty(ext) || !ext.StartsWith("."))
-            {
-                return DefaultMimeType;
-            }
-
-            ext = ext.Remove(0, 1);
-
-            if (MIMETypesDictionary.ContainsKey(ext))
-            {
-                return MIMETypesDictionary[ext];
-            }
-
-            return DefaultMimeType;
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/cordova-wp8/blob/e6fdbae4/wp7/template/cordovalib/NativeExecution.cs
----------------------------------------------------------------------
diff --git a/wp7/template/cordovalib/NativeExecution.cs b/wp7/template/cordovalib/NativeExecution.cs
deleted file mode 100644
index e8bda8f..0000000
--- a/wp7/template/cordovalib/NativeExecution.cs
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
-	Licensed under the Apache License, Version 2.0 (the "License");
-	you may not use this file except in compliance with the License.
-	You may obtain a copy of the License at
-
-	http://www.apache.org/licenses/LICENSE-2.0
-
-	Unless required by applicable law or agreed to in writing, software
-	distributed under the License is distributed on an "AS IS" BASIS,
-	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-	See the License for the specific language governing permissions and
-	limitations under the License.
-*/
-
-using System;
-using System.Diagnostics;
-using System.Threading;
-using Microsoft.Devices;
-using Microsoft.Phone.Controls;
-using WPCordovaClassLib.Cordova.Commands;
-using System.Windows;
-
-namespace WPCordovaClassLib.Cordova
-{
-    /// <summary>
-    /// Implements logic to execute native command and return result back.
-    /// All commands are executed asynchronous.
-    /// </summary>
-    public class NativeExecution
-    {
-        /// <summary>
-        /// Reference to web part where application is hosted
-        /// </summary>
-        private readonly WebBrowser webBrowser;
-
-        /// <summary>
-        /// Creates new instance of a NativeExecution class.
-        /// </summary>
-        /// <param name="browser">Reference to web part where application is hosted</param>
-        public NativeExecution(ref WebBrowser browser)
-        {
-            if (browser == null)
-            {
-                throw new ArgumentNullException("browser");
-            }
-
-            this.webBrowser = browser;
-        }
-
-        /// <summary>
-        /// Returns where application is running on emulator
-        /// </summary>
-        /// <returns>True if running on emulator, otherwise False</returns>
-        public static bool IsRunningOnEmulator()
-        {
-            return Microsoft.Devices.Environment.DeviceType == DeviceType.Emulator;
-        }
-
-        public void ResetAllCommands()
-        {
-            CommandFactory.ResetAllCommands();
-        }
-
-        public void AutoLoadCommand(string commandService)
-        {
-            BaseCommand bc = CommandFactory.CreateByServiceName(commandService);
-            if (bc != null)
-            {
-                bc.OnInit();
-            }
-
-        }
-
-        /// <summary>
-        /// Executes command and returns result back.
-        /// </summary>
-        /// <param name="commandCallParams">Command to execute</param>
-        public void ProcessCommand(CordovaCommandCall commandCallParams)
-        {
-
-            if (commandCallParams == null)
-            {
-                throw new ArgumentNullException("commandCallParams");
-            }
-
-            try
-            {
-                BaseCommand bc = CommandFactory.CreateByServiceName(commandCallParams.Service, commandCallParams.Namespace);
-
-                if (bc == null)
-                {
-                    this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.CLASS_NOT_FOUND_EXCEPTION));
-                    return;
-                }
-
-                EventHandler<PluginResult> OnCommandResultHandler = delegate(object o, PluginResult res)
-                {
-                    if (res.CallbackId == null || res.CallbackId == commandCallParams.CallbackId)
-                    {
-                        this.OnCommandResult(commandCallParams.CallbackId, res);
-                        if (!res.KeepCallback)
-                        {
-                            bc.RemoveResultHandler(commandCallParams.CallbackId);
-                        }
-                    }
-                };
-
-                //bc.OnCommandResult += OnCommandResultHandler;
-                bc.AddResultHandler(commandCallParams.CallbackId, OnCommandResultHandler);
-
-                EventHandler<ScriptCallback> OnCustomScriptHandler = delegate(object o, ScriptCallback script)
-                {
-                    this.InvokeScriptCallback(script);
-                };
-
-                bc.OnCustomScript += OnCustomScriptHandler;
-
-                ThreadStart methodInvokation = () =>
-                {
-                    try
-                    {
-                        bc.InvokeMethodNamed(commandCallParams.CallbackId, commandCallParams.Action, commandCallParams.Args);
-                    }
-                    catch (Exception ex)
-                    {
-                        Debug.WriteLine("ERROR: Exception in ProcessCommand :: " + ex.Message);
-                        bc.RemoveResultHandler(commandCallParams.CallbackId);
-                        bc.OnCustomScript -= OnCustomScriptHandler;
-
-                        Debug.WriteLine("ERROR: failed to InvokeMethodNamed :: " + commandCallParams.Action + " on Object :: " + commandCallParams.Service);
-                        this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.INVALID_ACTION));
-                        return;
-                    }
-                };
-
-                new Thread(methodInvokation).Start();
-
-            }
-            catch (Exception ex)
-            {
-                // ERROR
-                Debug.WriteLine(String.Format("ERROR: Unable to execute command :: {0}:{1}:{2} ",
-                    commandCallParams.Service, commandCallParams.Action, ex.Message));
-
-                this.OnCommandResult(commandCallParams.CallbackId, new PluginResult(PluginResult.Status.ERROR));
-                return;
-            }
-        }
-
-        /// <summary>
-        /// Handles command execution result.
-        /// </summary>
-        /// <param name="callbackId">Command callback identifier on client side</param>
-        /// <param name="result">Execution result</param>
-        private void OnCommandResult(string callbackId, PluginResult result)
-        {
-            #region  args checking
-
-            if (result == null)
-            {
-                Debug.WriteLine("ERROR: OnCommandResult missing result argument");
-                return;
-            }
-
-            if (String.IsNullOrEmpty(callbackId))
-            {
-                Debug.WriteLine("ERROR: OnCommandResult missing callbackId argument");
-                return;
-            }
-
-            if (!String.IsNullOrEmpty(result.CallbackId) && callbackId != result.CallbackId)
-            {
-                Debug.WriteLine("Multiple Overlapping Results :: " + result.CallbackId + " :: " + callbackId);
-                return;
-            }
-
-            #endregion
-
-            string jsonResult = result.ToJSONString();
-
-            string callback;
-            string args = string.Format("('{0}',{1});", callbackId, jsonResult);
-
-            if (result.Result == PluginResult.Status.NO_RESULT ||
-               result.Result == PluginResult.Status.OK)
-            {
-                callback = @"(function(callbackId,args) {
-                try { args.message = JSON.parse(args.message); } catch (ex) { }
-                cordova.callbackSuccess(callbackId,args);
-                })" + args;
-            }
-            else
-            {
-                callback = @"(function(callbackId,args) {
-                try { args.message = JSON.parse(args.message); } catch (ex) { }
-                cordova.callbackError(callbackId,args);
-                })" + args;
-            }
-            this.InvokeScriptCallback(new ScriptCallback("eval", new string[] { callback }));
-
-        }
-
-        /// <summary>
-        /// Executes client java script
-        /// </summary>
-        /// <param name="script">Script to execute on client side</param>
-        private void InvokeScriptCallback(ScriptCallback script)
-        {
-            if (script == null)
-            {
-                throw new ArgumentNullException("script");
-            }
-
-            if (String.IsNullOrEmpty(script.ScriptName))
-            {
-                throw new ArgumentNullException("ScriptName");
-            }
-
-            //Debug.WriteLine("INFO:: About to invoke ::" + script.ScriptName + " with args ::" + script.Args[0]);
-            this.webBrowser.Dispatcher.BeginInvoke((ThreadStart)delegate()
-            {
-                try
-                {
-                    //Debug.WriteLine("INFO:: InvokingScript::" + script.ScriptName + " with args ::" + script.Args[0]);
-                    this.webBrowser.InvokeScript(script.ScriptName, script.Args);
-                }
-                catch (Exception ex)
-                {
-                    Debug.WriteLine("ERROR: Exception in InvokeScriptCallback :: " + ex.Message);
-                }
-
-            });
-        }
-
-    }
-}
\ No newline at end of file


Mime
View raw message