private static void Invoke(
            MethodInfo method,
            int expectedArguments,
            IList <Func <IReactInstance, JArray, int, Result> > extractors,
            IGenericDelegate genericDelegate,
            INativeModule moduleInstance,
            IReactInstance reactInstance,
            JArray jsArguments)
        {
            if (moduleInstance == null)
            {
                throw new ArgumentNullException(nameof(moduleInstance));
            }
            if (reactInstance == null)
            {
                throw new ArgumentNullException(nameof(reactInstance));
            }
            if (jsArguments == null)
            {
                throw new ArgumentNullException(nameof(jsArguments));
            }

            var n = expectedArguments;
            var c = extractors.Count;

            if (jsArguments.Count != n)
            {
                throw new NativeArgumentsParseException(
                          Invariant($"Module '{moduleInstance.Name}' method '{method.Name}' got '{jsArguments.Count}' arguments, expected '{n}'."),
                          nameof(jsArguments));
            }

            var idx  = 0;
            var args = new object[extractors.Count];

            for (var j = 0; j < c; ++j)
            {
                var result = extractors[j](reactInstance, jsArguments, idx);
                args[j] = result.Value;
                idx     = result.NextIndex;
            }

            if (genericDelegate != null)
            {
                genericDelegate.Invoke(args);
            }
            else
            {
                // This should only happen for React methods with greater than 16 arguments.
                method.Invoke(moduleInstance, args);
            }
        }
        private static JToken Invoke(
            MethodInfo method,
            int expectedArguments,
            IList <ExtractArgument> extractors,
            IGenericDelegate genericDelegate,
            bool hasReturnType,
            INativeModule moduleInstance,
            InvokeCallback invokeCallback,
            JArray jsArguments)
        {
            if (moduleInstance == null)
            {
                throw new ArgumentNullException(nameof(moduleInstance));
            }
            if (invokeCallback == null)
            {
                throw new ArgumentNullException(nameof(invokeCallback));
            }
            if (jsArguments == null)
            {
                throw new ArgumentNullException(nameof(jsArguments));
            }

            var n = expectedArguments;
            var c = extractors.Count;

            if (jsArguments.Count != n)
            {
                throw new NativeArgumentsParseException(
                          Invariant($"Module '{moduleInstance.Name}' method '{method.Name}' got '{jsArguments.Count}' arguments, expected '{n}'."),
                          nameof(jsArguments));
            }

            var idx  = 0;
            var args = new object[extractors.Count];

            for (var j = 0; j < c; ++j)
            {
                var extractorResult = extractors[j](invokeCallback, jsArguments, idx);
                args[j] = extractorResult.Value;
                idx     = extractorResult.NextIndex;
            }

            object result;

            if (genericDelegate != null)
            {
                result = genericDelegate.Invoke(args);
            }
            else
            {
                // This should only happen for React methods with greater than 16 arguments.
                result = method.Invoke(moduleInstance, args);
            }

            if (!hasReturnType)
            {
                return(s_null);
            }
            else if (result == null)
            {
                return(s_null);
            }

            return(JToken.FromObject(result));
        }