private object UnwrapParamValue(JToken parameterToken, Type parameterType, IPluginManager pluginManager) { var defaultValue = new Func <object>(() => parameterToken.ToObject(parameterType)); var jobject = parameterToken as JObject; if (jobject != null) { if (jobject.Type == JTokenType.Object) { if (parameterType == typeof(object)) { return(defaultValue()); } if (parameterType == typeof(string)) { // If the parameter is a JSON object, but the parameter type is string return the raw JSON. return(jobject.ToString()); } JToken typeValue, payload; if (!jobject.TryGetValue("__type__", out typeValue) || !jobject.TryGetValue("__payload__", out payload)) { return(defaultValue()); } var payloadJObj = payload as JObject; if (payloadJObj == null) { return(defaultValue()); } if (payloadJObj.Type != JTokenType.Object) { return(defaultValue()); } if ((string)typeValue != "reference") { return(defaultValue()); } JToken dynamicPluginGuid; if (!payloadJObj.TryGetValue("id", out dynamicPluginGuid)) { return(defaultValue()); } var dynamicPlugin = pluginManager.GetLocalPlugin((string)dynamicPluginGuid); if (dynamicPlugin != null) { return(dynamicPlugin.NativeObject); } throw new NullReferenceException("Failed to map Javascript parameter to native dynamic plugin object "); } } var jarray = parameterToken as JArray; if (jarray != null) { if (jarray.Type != JTokenType.Array) { return(defaultValue()); } if (parameterType == typeof(object)) { return(defaultValue()); } var elementType = parameterType.GetElementType(); if (elementType == null) { if (!typeof(JArray).IsAssignableFrom(parameterType) && !typeof(Array).IsAssignableFrom(parameterType)) { return(parameterType == typeof(string) ? jarray.ToString() : null); } if (typeof(JArray).IsAssignableFrom(parameterType)) { return(defaultValue()); } } elementType = elementType ?? typeof(object); var nativeArray = Array.CreateInstance(elementType, jarray.Count); for (var i = 0; i < jarray.Count; i++) { nativeArray.SetValue(Convert.ChangeType(UnwrapParamValue(jarray[i], elementType, pluginManager), elementType), i); } return(nativeArray); } return(defaultValue()); }