protected virtual void OnComplete(InvokeAsyncEventArgs e)
        {
            EventHandler <InvokeAsyncEventArgs> handler = complete;

            if (handler != null)
            {
                handler(this, e);
            }
        }
        public async void run(object instance, MethodInfo methodInfo, object[] fnArguments)
        {
            SynchronizationContext ctx = SynchronizationContext.Current;

            if (!methodInfo.ReturnType.GetInterfaces().Contains(typeof(IAsyncInfo)))
            {
                // this should be easy, just run it as if it was synchronous
                var result = methodInfo.Invoke(instance, fnArguments);

                InvokeAsyncEventArgs eventArgs = new InvokeAsyncEventArgs();

                if (methodInfo.ReturnType == typeof(void))
                {
                    eventArgs.primitiveValue = null;
                }
                else
                {
                    Type type = result.GetType();
                    if (type.IsPrimitive || type == typeof(string) || type == typeof(decimal))
                    {
                        eventArgs.primitiveValue = result;
                    }
                    else if (InstanceRegistry.containsInstance(result))
                    {
                        eventArgs.handle = InstanceRegistry.getInstanceHandleByValue(result);
                    }
                    else
                    {
                        string handle = InstanceRegistry.createHandle(result);
                        eventArgs.handle = handle;
                    }
                }

                this.OnComplete(eventArgs);
                return;
            }

            MethodInfo castMethod = Type.GetType("TitaniumApp.TiRequestHandlers.AsyncAwaiter").GetMethod("awaitTask");

            castMethod = castMethod.MakeGenericMethod(methodInfo.ReturnType.GenericTypeArguments[0]);

            InvokeAsync _this = this;

            Task.Run(() => {
                var comObject = methodInfo.Invoke(instance, fnArguments);

                Task <object> obj = (Task <object>)castMethod.Invoke(null, new object[] { comObject });
                obj.Wait();
                var result = obj.Result;

                InvokeAsyncEventArgs eventArgs = new InvokeAsyncEventArgs();

                if (methodInfo.ReturnType == typeof(void))
                {
                    eventArgs.primitiveValue = null;
                }
                else
                {
                    Type type = result.GetType();
                    if (type.IsPrimitive || type == typeof(string) || type == typeof(decimal))
                    {
                        eventArgs.primitiveValue = result;
                    }
                    else if (InstanceRegistry.containsInstance(result))
                    {
                        eventArgs.handle = InstanceRegistry.getInstanceHandleByValue(result);
                    }
                    else
                    {
                        string handle    = InstanceRegistry.createHandle(result);
                        eventArgs.handle = handle;
                    }
                }

                ctx.Post(args => {
                    _this.OnComplete((InvokeAsyncEventArgs)args);
                }, eventArgs);
            });
        }