public static TiResponse createReturnType(object value)
        {
            Type       type     = value == null ? null : value.GetType();
            TiResponse response = new TiResponse();
            string     handle   = null;

            if (value == null || type.IsPrimitive || type == typeof(string) || type == typeof(decimal))
            {
                response["primitiveValue"] = value;
                return(response);
            }

            foreach (string key in instances.Keys)
            {
                if (instances[key].Equals(value))
                {
                    handle = key;
                    break;
                }
            }

            if (handle == null)
            {
                handle = createHandle(value);
            }

            response["handle"] = handle;
            return(response);
        }
        public static TiResponse createReturnType(object value)
        {
            Type type = value == null ? null : value.GetType();
            TiResponse response = new TiResponse();
            string handle = null;

            if (value == null || type.IsPrimitive || type == typeof(string) || type == typeof(decimal)) {
                response["primitiveValue"] = value;
                return response;
            }

            foreach (string key in instances.Keys) {
                if (instances[key].Equals(value)) {
                    handle = key;
                    break;
                }
            }

            if (handle == null) {
                handle = createHandle(value);
            }

            response["handle"] = handle;
            return response;
        }
Example #3
0
        private void browser_ScriptNotify(object sender, NotifyEventArgs e)
        {
            try {
                TiRequest  request = JsonConvert.DeserializeObject <TiRequest>(e.Value);
                TiResponse response;

                if (request.stoken != this.securityToken)
                {
                    // token mismatch, ignore request
                    return;
                }

                try {
                    if (request.type == null)
                    {
                        throw new Exception("Request Exception: Missing request \"type\" param");
                    }

                    if (!requestHandlers.ContainsKey(request.type))
                    {
                        throw new Exception("Request Exception: Invalid request type \"" + request.type + "\"");
                    }

                    if (request.data == null)
                    {
                        throw new Exception("Request Exception: Missing request \"data\" param");
                    }

                    response = requestHandlers[request.type].process(request.data);
                } catch (Exception ex) {
                    response          = new TiResponse();
                    response["error"] = ex.ToString();
                }

                // if the handler doesn't have a response, then just return
                if (response == null)
                {
                    return;
                }

                // if the request has a token, then add it to the response
                if (request.rtoken != null)
                {
                    response["rtoken"] = request.rtoken;
                }

                // pass the response back to the browser
                browser.InvokeScript("execScript", new string[] { "tiwp8.handleResponse(" + JsonConvert.SerializeObject(response, Formatting.None) + ")" });
            } catch { }
        }
        private void eventHandler(Object sender, EventArgs e, String eventName, String handle, WebBrowser browser)
        {
            TiResponse response = new TiResponse();

            response["_hnd"] = handle;
            response["type"] = eventName;

            string senderHandle = "";
            bool   senderExists = InstanceRegistry.containsInstance(sender);

            if (senderExists)
            {
                senderHandle = InstanceRegistry.getInstanceHandleByValue(sender);
            }
            else
            {
                senderHandle = InstanceRegistry.createHandle(sender);
            }
            response["sender"] = senderHandle;

            string eventArgsHandle = "";
            bool   eventArgsExists = InstanceRegistry.containsInstance(e);

            if (eventArgsExists)
            {
                eventArgsHandle = InstanceRegistry.getInstanceHandleByValue(e);
            }
            else
            {
                eventArgsHandle = InstanceRegistry.createHandle(e);
            }
            response["eventArgs"] = eventArgsHandle;

            response["error"] = null;
            if (e.GetType() == typeof(ErrorEventArgs))
            {
                response["error"] = ((ErrorEventArgs)e).error;
            }

            browser.InvokeScript("execScript", new string[] { "tiwp8.fireEvent(" + JsonConvert.SerializeObject(response, Formatting.None) + ")" });

            if (!senderExists)
            {
                InstanceRegistry.removeInstance(senderHandle);
            }
            if (!eventArgsExists)
            {
                InstanceRegistry.removeInstance(eventArgsHandle);
            }
        }
Example #5
0
        public TiResponse process(TiRequestParams data)
        {
            if (!data.ContainsKey("file"))
            {
                throw new FileRequestException("Request missing 'file' param");
            }

            string file = collapsePath((string)data["file"]);

            if (file.IndexOf("..") == 0)
            {
                throw new FileRequestException("The requested file must not begin with \"..\"");
            }
            file = "App/" + file;

            if (!File.Exists(file))
            {
                throw new FileRequestException("File \"" + file + "\" does not exist");
            }

            bool isBinary = false;

            if (data.ContainsKey("isBinary"))
            {
                isBinary = (bool)data["isBinary"];
            }

            TiResponse response = new TiResponse();

            response["file"] = file;

            if (isBinary)
            {
                var    filestream = new FileStream(file, FileMode.Open);
                byte[] bytes      = new byte[filestream.Length];
                filestream.Read(bytes, 0, (int)filestream.Length);
                response["encoding"] = "base64";
                response["contents"] = Convert.ToBase64String(bytes);
            }
            else
            {
                response["contents"] = (new StreamReader(file)).ReadToEnd();
            }

            return(response);
        }
Example #6
0
        public static TiResponse createReturnType(object value)
        {
            Type type = value == null ? null : value.GetType();
            TiResponse response = new TiResponse();

            if (value == null || type.IsPrimitive || type == typeof(string) || type == typeof(decimal)) {
                response["primitiveValue"] = value;
                return response;
            }

            if (instances.ContainsValue(value)) {
                response["handle"] = instances.FirstOrDefault(x => x.Value == value).Key;
                return response;
            }

            string handle = createHandle(value);
            response["handle"] = handle;
            return response;
        }
Example #7
0
        void browser_ScriptNotify(object sender, NotifyEventArgs e)
        {
            TiRequest request = JsonConvert.DeserializeObject<TiRequest>(e.Value);
            TiResponse response;

            try {
                if (request.type == null) {
                    throw new Exception("Request Exception: Missing request \"type\" param");
                }

                if (!requestHandlers.ContainsKey(request.type)) {
                    throw new Exception("Request Exception: Invalid request type \"" + request.type + "\"");
                }

                if (request.data == null) {
                    throw new Exception("Request Exception: Missing request \"data\" param");
                }

                response = requestHandlers[request.type].process(request.data);
            } catch (Exception ex) {
                response = new TiResponse();
                response["error"] = ex.ToString();
            }

            // if the handler doesn't have a response, then just return
            if (response == null) {
                return;
            }

            // if the request has a token, then add it to the response
            if (request.token != null) {
                response["token"] = request.token;
            }

            // pass the response back to the browser
            try {
                browser.InvokeScript("execScript", new string[] { "tiwp8.handleResponse(" + JsonConvert.SerializeObject(response, Formatting.None) + ")" });
            } catch { }
        }
        public TiResponse process(TiRequestParams data)
        {
            if (!data.ContainsKey("file")) {
                throw new FileRequestException("Request missing 'file' param");
            }

            string file = collapsePath((string)data["file"]);
            if (file.IndexOf("..") == 0) {
                throw new FileRequestException("The requested file must not begin with \"..\"");
            }
            file = "App/" + file;

            if (!File.Exists(file)) {
                throw new FileRequestException("File \"" + file + "\" does not exist");
            }

            bool isBinary = false;
            if (data.ContainsKey("isBinary")) {
                isBinary = (bool)data["isBinary"];
            }

            TiResponse response = new TiResponse();
            response["file"] = file;

            if (isBinary) {
                var filestream = new FileStream(file, FileMode.Open);
                byte[] bytes = new byte[filestream.Length];
                filestream.Read(bytes, 0, (int)filestream.Length);
                response["encoding"] = "base64";
                response["contents"] = Convert.ToBase64String(bytes);
            } else {
                response["contents"] = (new StreamReader(file)).ReadToEnd();
            }

            return response;
        }
        private void eventHandler(Object sender, EventArgs e, String eventName, String handle, WebBrowser browser)
        {
            TiResponse response = new TiResponse();
            response["_hnd"] = handle;
            response["type"] = eventName;

            if ((uint)instanceCount + 1 > UInt32.MaxValue) {
                throw new Exception("Reflection Handler Exception: Maximum instance count exceeded");
            }

            string senderHandle = instanceCount++.ToString();
            instances[senderHandle] = sender;
            response["sender"] = senderHandle;

            string eventArgsHandle = instanceCount++.ToString();
            instances[eventArgsHandle] = e;
            response["eventArgs"] = eventArgsHandle;

            browser.InvokeScript("execScript", new string[] { "tiwp8.fireEvent(" + JsonConvert.SerializeObject(response, Formatting.None) + ")" });

            instances.Remove(senderHandle);
            instances.Remove(eventArgsHandle);
        }
		public TiResponse process(TiRequestParams data) {
			if (!data.ContainsKey("url")) {
				throw new DownloadException("Request missing 'url' param");
			}

			string url = (string)data["url"];

			if (!url.StartsWith("http://") && !url.StartsWith("https://")) {
				throw new DownloadException("'url' param must start with 'http://' or 'https://'");
			}

			string saveTo = "";
			int p;

			if (data.ContainsKey("saveTo")) {
				saveTo = (string)data["saveTo"];
			} else {
				// try to determine the filename based on the URL
				p = url.LastIndexOf('/');
				if (p > 8 && p != -1) { // make sure the last / is after the ://
					saveTo = url.Substring(p + 1);
				} else {
					throw new DownloadException("Request missing 'saveTo' param");
				}
			}

			if (saveTo == null || saveTo == "") {
				throw new DownloadException("Invalid 'saveTo' param");
			}

			saveTo = saveTo.Replace('\\', '/');

			IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

			p = saveTo.LastIndexOf('\\');
			if (p != -1) {
				string dir = saveTo.Substring(0, p);
				try {
					if (!isf.DirectoryExists(dir)) {
						isf.CreateDirectory(dir);
					}
				} catch (IsolatedStorageException ise) {
					throw new DownloadException("Unable to create destination directory '" + dir + "' because of insufficient permissions or the isolated storage has been disabled or removed");
				}
			}

			if (isf.FileExists(saveTo)) {
				if (data.ContainsKey("overwrite") && (bool)data["overwrite"]) {
					isf.DeleteFile(saveTo);
				} else {
					throw new DownloadException("File '" + saveTo + "' already exists");
				}
			}

			IsolatedStorageFileStream fileStream = null;

			try {
				fileStream = isf.CreateFile(saveTo);
			} catch (IsolatedStorageException ise) {
				throw new DownloadException("Unable to create file '" + saveTo + "' because the isolated storage has been disabled or removed");
			} catch (DirectoryNotFoundException dnfe) {
				throw new DownloadException("Unable to create file '" + saveTo + "' because the directory does not exist");
			} catch (ObjectDisposedException dnfe) {
				throw new DownloadException("Unable to create file '" + saveTo + "' because the isolated storage has been disposed");
			}

			TiResponse response = new TiResponse();
			DownloadFile df = new DownloadFile(SynchronizationContext.Current, new Uri(url), fileStream);
			response["handle"] = InstanceRegistry.createHandle(df);

			return response;
		}
        private TiResponse property(TiRequestParams data)
        {
            if (!data.ContainsKey("handle"))
            {
                throw new ReflectionException("\"property\" request missing \"handle\" param");
            }

            string handle   = (string)data["handle"];
            object instance = InstanceRegistry.getInstance(handle);

            if (instance == null)
            {
                throw new ReflectionException("\"property\" request invalid handle \"" + handle + "\"");
            }

            if (!data.ContainsKey("name"))
            {
                throw new ReflectionException("\"property\" request missing \"name\" param");
            }

            var obj = data["name"];

            if (obj == null)
            {
                throw new ReflectionException("\"property\" request \"name\" is null");
            }

            Type instanceType = instance.GetType();
            Type propType     = instanceType.GetType();

            TiResponse response = new TiResponse();

            response["value"] = null;

            switch (obj.GetType().ToString())
            {
            case "Newtonsoft.Json.Linq.JArray":
            {
                // get multiple props
                JArray arr = (JArray)obj;
                Dictionary <string, TiResponse> value = new Dictionary <string, TiResponse>();
                for (var i = 0; i < arr.Count; i++)
                {
                    string propName     = arr[i].ToString();
                    var    propertyInfo = instanceType.GetProperty(propName);
                    if (propertyInfo == null)
                    {
                        throw new ReflectionException("Invalid property \"" + propName + "\"");
                    }
                    object val = propertyInfo.GetValue(instance);
                    value[propName] = InstanceRegistry.createReturnType(val);
                }
                response["value"] = value;
                return(response);
            }

            case "Newtonsoft.Json.Linq.JObject":
            {
                // set multiple props
                JObject props = (JObject)obj;
                foreach (JProperty prop in props.Properties())
                {
                    var propertyInfo = instanceType.GetProperty(prop.Name);
                    if (propertyInfo == null)
                    {
                        throw new ReflectionException("Invalid property \"" + prop.Name + "\"");
                    }
                    JObject value = (JObject)prop.Value;
                    if (value["valueHnd"] != null)
                    {
                        propertyInfo.SetValue(instance, InstanceRegistry.getInstance((string)value["valueHnd"]));
                    }
                    else if (value["valuePrimitive"] != null)
                    {
                        var valuePrimitive = value["valuePrimitive"];
                        if (propertyInfo.PropertyType == typeof(Uri))
                        {
                            propertyInfo.SetValue(instance, Convert.ChangeType(new Uri(valuePrimitive.ToObject <string>(), UriKind.RelativeOrAbsolute), propertyInfo.PropertyType));
                        }
                        else
                        {
                            propertyInfo.SetValue(instance, valuePrimitive.ToObject(propertyInfo.PropertyType));
                        }
                    }
                }

                return(null);
            }

            case "System.String":
            {
                string name         = (string)obj;
                var    propertyInfo = instanceType.GetProperty(name);
                if (propertyInfo == null)
                {
                    throw new ReflectionException("Invalid property \"" + name + "\"");
                }

                // setting a single prop
                if (data.ContainsKey("valueHnd") && data["valueHnd"] != null)
                {
                    propertyInfo.SetValue(instance, InstanceRegistry.getInstance((string)data["valueHnd"]));
                    return(null);
                }
                else if (data.ContainsKey("valuePrimitive"))
                {
                    var valuePrimitive = data["valuePrimitive"];
                    if (propertyInfo.PropertyType == typeof(Uri))
                    {
                        valuePrimitive = new Uri((string)valuePrimitive, UriKind.RelativeOrAbsolute);
                    }
                    propertyInfo.SetValue(instance, Convert.ChangeType(valuePrimitive, propertyInfo.PropertyType));
                    return(null);
                }

                // getting a single prop
                object val = propertyInfo.GetValue(instance);
                return(InstanceRegistry.createReturnType(val));
            }
            }

            return(null);
        }
        private TiResponse invokeStaticAsync(TiRequestParams data)
        {
            if (!data.ContainsKey("className"))
            {
                throw new ReflectionException("\"invokeStatic\" request missing \"className\" param");
            }

            string className = (string)data["className"];
            var    classType = InstanceRegistry.lookupType(className);

            if (classType == null)
            {
                throw new ReflectionException("\"invokeStatic\" request invalid classname \"" + className + "\"");
            }

            if (!data.ContainsKey("method"))
            {
                throw new ReflectionException("\"invokeStatic\" request missing \"method\" param");
            }

            if (!data.ContainsKey("args"))
            {
                throw new ReflectionException("\"invokeStatic\" request missing \"args\" param");
            }

            JArray args = (JArray)data["args"];

            if (args.Count % 2 != 0)
            {
                throw new ReflectionException("\"invokeStatic\" request arguments must contain an even number of type-values");
            }

            // create the argument types array
            Type[] fnArgumentTypes = new Type[args.Count / 2];
            for (int i = 0, j = 0; i < args.Count; i += 2, j++)
            {
                fnArgumentTypes[j] = InstanceRegistry.lookupType((string)args[i]);
            }

            // get the method info
            MethodInfo methodInfo = classType.GetMethod((string)data["method"], fnArgumentTypes);

            // create the argument values array
            object[] fnArguments = new object[args.Count / 2];
            for (int i = 1, j = 0; i < args.Count; i += 2, j++)
            {
                JObject arg = (JObject)args[i];
                if (arg["valueHnd"] != null)
                {
                    fnArguments[j] = InstanceRegistry.getInstance((string)arg["valueHnd"]);
                }
                else if (fnArgumentTypes[j] == typeof(Uri))
                {
                    fnArguments[j] = new Uri((string)arg["valuePrimitive"], UriKind.RelativeOrAbsolute);
                }
                else
                {
                    fnArguments[j] = ((JValue)arg["valuePrimitive"]).Value;
                }
                if (fnArguments[j] != null)
                {
                    IConvertible convertible = fnArguments[j] as IConvertible;
                    if (convertible != null)
                    {
                        fnArguments[j] = Convert.ChangeType(fnArguments[j], fnArgumentTypes[j]);
                    }
                }
            }

            TiResponse  response = new TiResponse();
            InvokeAsync ia       = new InvokeAsync();

            response["handle"] = InstanceRegistry.createHandle(ia);
            ia.run(null, methodInfo, fnArguments);

            return(response);
        }
        private TiResponse createInstance(TiRequestParams data)
        {
            if (!data.ContainsKey("className"))
            {
                throw new ReflectionException("\"createInstance\" request missing \"className\" param");
            }

            string className = (string)data["className"];
            var    classType = InstanceRegistry.lookupType(className);

            if (classType == null)
            {
                throw new ReflectionException("\"createInstance\" request invalid classname \"" + classType + "\"");
            }

            if (!data.ContainsKey("args"))
            {
                throw new ReflectionException("\"createInstance\" request missing \"args\" param");
            }

            JArray args = (JArray)data["args"];

            if (args.Count % 2 != 0)
            {
                throw new ReflectionException("\"createInstance\" request arguments must contain an even number of type-values");
            }

            // create the argument types array
            Type[] ctorArgumentTypes = new Type[args.Count / 2];
            for (int i = 0, j = 0; i < args.Count; i += 2, j++)
            {
                ctorArgumentTypes[j] = InstanceRegistry.lookupType((string)args[i]);
            }

            // create the argument values array
            object[] ctorArguments = new object[args.Count / 2];
            for (int i = 1, j = 0; i < args.Count; i += 2, j++)
            {
                JObject arg = (JObject)args[i];
                if (arg["valueHnd"] != null)
                {
                    ctorArguments[j] = InstanceRegistry.getInstance((string)arg["valueHnd"]);
                }
                else if (ctorArgumentTypes[j] == typeof(Uri))
                {
                    ctorArguments[j] = new Uri((string)arg["valuePrimitive"], UriKind.RelativeOrAbsolute);
                }
                else
                {
                    ctorArguments[j] = ((JValue)arg["valuePrimitive"]).Value;
                }
                if (ctorArguments[j] != null)
                {
                    ctorArguments[j] = Convert.ChangeType(ctorArguments[j], ctorArgumentTypes[j]);
                }
            }

            // Invoke the constructor and return the result
            var instance = classType.GetConstructor(ctorArgumentTypes).Invoke(ctorArguments);

            TiResponse response = new TiResponse();

            response["handle"] = InstanceRegistry.createHandle(instance);
            return(response);
        }
        private TiResponse property(TiRequestParams data)
        {
            if (!data.ContainsKey("handle")) {
                throw new Exception("Reflection Handler Exception: \"property\" request missing \"handle\" param");
            }

            string handle = (string)data["handle"];

            if (!instances.ContainsKey(handle)) {
                throw new Exception("Reflection Handler Exception: \"property\" request invalid handle \"" + handle + "\"");
            }

            if (!data.ContainsKey("name")) {
                throw new Exception("Reflection Handler Exception: \"property\" request missing \"name\" param");
            }

            var obj = data["name"];
            if (obj == null) {
                throw new Exception("Reflection Handler Exception: \"property\" request \"name\" is null");
            }

            var instance = instances[handle];
            Type instanceType = instance.GetType();
            Type propType = instanceType.GetType();

            TiResponse response = new TiResponse();
            response["value"] = null;

            switch (obj.GetType().ToString()) {
                case "Newtonsoft.Json.Linq.JArray":
                    {
                        // get multiple props
                        JArray arr = (JArray)obj;
                        Dictionary<string, TiResponse> value = new Dictionary<string, TiResponse>();
                        for (var i = 0; i < arr.Count; i++) {
                            string propName = arr[i].ToString();
                            object val = instanceType.GetProperty(propName).GetValue(instance);
                            value[propName] = createReturnType(val.GetType(), val);
                        }
                        response["value"] = value;
                        return response;
                    }

                case "Newtonsoft.Json.Linq.JObject":
                    {
                        // set multiple props
                        JObject props = (JObject)obj;
                        foreach (JProperty prop in props.Properties()) {
                            var propertyInfo = instanceType.GetProperty(prop.Name);
                            JObject value = (JObject)prop.Value;
                            if (value["valueHnd"] != null) {
                                propertyInfo.SetValue(instance, instances[(string)value["valueHnd"]]);
                            } else if (value["valuePrimitive"] != null) {
                                var valuePrimitive = value["valuePrimitive"];
                                if (propertyInfo.PropertyType == typeof(Uri)) {
                                    propertyInfo.SetValue(instance, Convert.ChangeType(new Uri(valuePrimitive.ToObject<string>(), UriKind.RelativeOrAbsolute), propertyInfo.PropertyType));
                                } else {
                                    propertyInfo.SetValue(instance, valuePrimitive.ToObject(propertyInfo.PropertyType));
                                }
                            }
                        }

                        return null;
                    }

                case "System.String":
                    {
                        string name = (string)obj;
                        var propertyInfo = instanceType.GetProperty(name);

                        // setting a single prop
                        if (data.ContainsKey("valueHnd") && data["valueHnd"] != null) {
                            propertyInfo.SetValue(instance, instances[(string)data["valueHnd"]]);
                            return null;
                        } else if (data.ContainsKey("valuePrimitive")) {
                            var valuePrimitive = data["valuePrimitive"];
                            if (propertyInfo.PropertyType == typeof(Uri)) {
                                valuePrimitive = new Uri((string)valuePrimitive, UriKind.RelativeOrAbsolute);
                            }
                            propertyInfo.SetValue(instance, Convert.ChangeType(valuePrimitive, propertyInfo.PropertyType));
                            return null;
                        }

                        // getting a single prop
                        object val = propertyInfo.GetValue(instance);
                        return createReturnType(val.GetType(), val);
                    }
            }

            return null;
        }
        private TiResponse createReturnType(Type type, object value)
        {
            TiResponse response = new TiResponse();

            if (value == null || type.IsPrimitive || type == typeof(string) || type == typeof(decimal)) {
                response["primitiveValue"] = value;
                return response;
            }

            if (instances.ContainsValue(value)) {
                response["handle"] = instances.FirstOrDefault(x => x.Value == value).Key;
                return response;
            }

            if ((uint)instanceCount > UInt32.MaxValue) {
                throw new Exception("Reflection Handler Exception: Maximum instance count exceeded");
            }

            string handle = instanceCount++.ToString();
            instances[handle] = value;

            response["handle"] = handle;
            return response;
        }
        private TiResponse createInstance(TiRequestParams data)
        {
            if (!data.ContainsKey("className")) {
                throw new Exception("Reflection Handler Exception: \"createInstance\" request missing \"className\" param");
            }

            string className = (string)data["className"];
            var classType = lookupType(className);
            if (classType == null) {
                throw new Exception("Reflection Handler Exception: \"createInstance\" request invalid classname \"" + classType + "\"");
            }

            if (!data.ContainsKey("args")) {
                throw new Exception("Reflection Handler Exception: \"createInstance\" request missing \"args\" param");
            }

            JArray args = (JArray)data["args"];
            if (args.Count % 2 != 0) {
                throw new Exception("Reflection Handler Exception: \"createInstance\" request arguments must contain an even number of type-values");
            }

            // create the argument types array
            Type[] ctorArgumentTypes = new Type[args.Count / 2];
            for (int i = 0, j = 0; i < args.Count; i += 2, j++) {
                ctorArgumentTypes[j] = lookupType((string)args[i]);
            }

            // create the argument values array
            object[] ctorArguments = new object[args.Count / 2];
            for (int i = 1, j = 0; i < args.Count; i += 2, j++) {
                JObject arg = (JObject)args[i];
                if (arg["valueHnd"] != null) {
                    ctorArguments[j] = instances[(string)arg["valueHnd"]];
                } else if (ctorArgumentTypes[j] == typeof(Uri)) {
                    ctorArguments[j] = new Uri((string)arg["valuePrimitive"], UriKind.RelativeOrAbsolute);
                } else {
                    ctorArguments[j] = ((JValue)arg["valuePrimitive"]).Value;
                }
                if (ctorArguments[j] != null) {
                    ctorArguments[j] = Convert.ChangeType(ctorArguments[j], ctorArgumentTypes[j]);
                }
            }

            if ((uint)instanceCount > UInt32.MaxValue) {
                throw new Exception("Reflection Handler Exception: Maximum instance count exceeded");
            }

            // Invoke the constructor and return the result
            var instance = classType.GetConstructor(ctorArgumentTypes).Invoke(ctorArguments);

            string handle = instanceCount++.ToString();
            instances[handle] = instance;

            TiResponse response = new TiResponse();
            response["handle"] = handle;
            return response;
        }
        public TiResponse process(TiRequestParams data)
        {
            if (!data.ContainsKey("url"))
            {
                throw new DownloadException("Request missing 'url' param");
            }

            string url = (string)data["url"];

            if (!url.StartsWith("http://") && !url.StartsWith("https://"))
            {
                throw new DownloadException("'url' param must start with 'http://' or 'https://'");
            }

            string saveTo = "";
            int    p;

            if (data.ContainsKey("saveTo"))
            {
                saveTo = (string)data["saveTo"];
            }
            else
            {
                // try to determine the filename based on the URL
                p = url.LastIndexOf('/');
                if (p > 8 && p != -1)                   // make sure the last / is after the ://
                {
                    saveTo = url.Substring(p + 1);
                }
                else
                {
                    throw new DownloadException("Request missing 'saveTo' param");
                }
            }

            if (saveTo == null || saveTo == "")
            {
                throw new DownloadException("Invalid 'saveTo' param");
            }

            saveTo = saveTo.Replace('\\', '/');

            IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

            p = saveTo.LastIndexOf('\\');
            if (p != -1)
            {
                string dir = saveTo.Substring(0, p);
                try {
                    if (!isf.DirectoryExists(dir))
                    {
                        isf.CreateDirectory(dir);
                    }
                } catch (IsolatedStorageException) {
                    throw new DownloadException("Unable to create destination directory '" + dir + "' because of insufficient permissions or the isolated storage has been disabled or removed");
                }
            }

            if (isf.FileExists(saveTo))
            {
                if (data.ContainsKey("overwrite") && (bool)data["overwrite"])
                {
                    isf.DeleteFile(saveTo);
                }
                else
                {
                    throw new DownloadException("File '" + saveTo + "' already exists");
                }
            }

            IsolatedStorageFileStream fileStream = null;

            try {
                fileStream = isf.CreateFile(saveTo);
            } catch (IsolatedStorageException) {
                throw new DownloadException("Unable to create file '" + saveTo + "' because the isolated storage has been disabled or removed");
            } catch (DirectoryNotFoundException) {
                throw new DownloadException("Unable to create file '" + saveTo + "' because the directory does not exist");
            } catch (ObjectDisposedException) {
                throw new DownloadException("Unable to create file '" + saveTo + "' because the isolated storage has been disposed");
            }

            TiResponse   response = new TiResponse();
            DownloadFile df       = new DownloadFile(SynchronizationContext.Current, new Uri(url), fileStream);

            response["handle"] = InstanceRegistry.createHandle(df);

            return(response);
        }