Beispiel #1
0
        private static object ParseFunction(string functionString, string inputJson, JArray array, JToken currentArrayElement, JUSTContext localContext)
        {
            try
            {
                object output;

                string functionName, argumentString;
                if (!ExpressionHelper.TryParseFunctionNameAndArguments(functionString, out functionName, out argumentString))
                {
                    return(functionName);
                }

                string[] arguments      = ExpressionHelper.GetArguments(argumentString);
                var      listParameters = new List <object>();

                if (functionName == "ifcondition")
                {
                    var condition = ParseArgument(inputJson, array, currentArrayElement, arguments[0], localContext);
                    var value     = ParseArgument(inputJson, array, currentArrayElement, arguments[1], localContext);
                    var index     = condition.ToString().ToLower() == value.ToString().ToLower() ? 2 : 3;
                    output = ParseArgument(inputJson, array, currentArrayElement, arguments[index], localContext);
                }
                else
                {
                    int i = 0;
                    for (; i < (arguments?.Length ?? 0); i++)
                    {
                        listParameters.Add(ParseArgument(inputJson, array, currentArrayElement, arguments[i], localContext));
                    }

                    listParameters.Add(localContext ?? GlobalContext);
                    var parameters = listParameters.ToArray();

                    if (new[] { "currentvalue", "currentindex", "lastindex", "lastvalue" }.Contains(functionName))
                    {
                        output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement }, true, localContext ?? GlobalContext);
                    }
                    else if (new[] { "currentvalueatpath", "lastvalueatpath" }.Contains(functionName))
                    {
                        output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, new object[] { array, currentArrayElement, parameters[0] }, true, localContext ?? GlobalContext);
                    }
                    else if (functionName == "currentproperty")
                    {
                        output = ReflectionHelper.caller(null, "JUST.Transformer", functionName,
                                                         new object[] { array, currentArrayElement, localContext ?? GlobalContext },
                                                         false, localContext ?? GlobalContext);
                    }
                    else if (functionName == "customfunction")
                    {
                        output = CallCustomFunction(parameters, localContext);
                    }
                    else if (localContext?.IsRegisteredCustomFunction(functionName) ?? false)
                    {
                        var methodInfo = localContext.GetCustomMethod(functionName);
                        output = ReflectionHelper.InvokeCustomMethod(methodInfo, parameters, true, localContext ?? GlobalContext);
                    }
                    else if (GlobalContext.IsRegisteredCustomFunction(functionName))
                    {
                        var methodInfo = GlobalContext.GetCustomMethod(functionName);
                        output = ReflectionHelper.InvokeCustomMethod(methodInfo, parameters, true, localContext ?? GlobalContext);
                    }
                    else if (Regex.IsMatch(functionName, ReflectionHelper.EXTERNAL_ASSEMBLY_REGEX))
                    {
                        output = ReflectionHelper.CallExternalAssembly(functionName, parameters, localContext ?? GlobalContext);
                    }
                    else if (new[] { "xconcat", "xadd",
                                     "mathequals", "mathgreaterthan", "mathlessthan", "mathgreaterthanorequalto", "mathlessthanorequalto",
                                     "stringcontains", "stringequals" }.Contains(functionName))
                    {
                        object[] oParams = new object[1];
                        oParams[0] = parameters;
                        output     = ReflectionHelper.caller(null, "JUST.Transformer", functionName, oParams, true, localContext ?? GlobalContext);
                    }
                    else if (functionName == "applyover")
                    {
                        var contextInput = GetInputToken(localContext);
                        var input        = JToken.Parse(Transform(parameters[0].ToString(), contextInput.ToString(), localContext));
                        (localContext ?? GlobalContext).Input = input;
                        output = ParseFunction(parameters[1].ToString().Trim('\''), inputJson, array, currentArrayElement, localContext ?? GlobalContext);
                        (localContext ?? GlobalContext).Input = contextInput;
                    }
                    else
                    {
                        var input = ((JUSTContext)parameters.Last()).Input;
                        if (currentArrayElement != null && functionName != "valueof")
                        {
                            ((JUSTContext)parameters.Last()).Input = currentArrayElement;
                        }
                        output = ReflectionHelper.caller(null, "JUST.Transformer", functionName, parameters, true, localContext ?? GlobalContext);
                        ((JUSTContext)parameters.Last()).Input = input;
                    }
                }

                return(output);
            }
            catch (Exception ex)
            {
                throw new Exception("Error while calling function : " + functionString + " - " + ex.Message, ex);
            }
        }
Beispiel #2
0
        private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArray parentArray, JToken currentArrayToken, JUSTContext localContext)
        {
            if (parentToken == null)
            {
                return;
            }

            JEnumerable <JToken> tokens = parentToken.Children();

            List <JToken> selectedTokens = null;
            Dictionary <string, JToken> tokensToReplace = null;
            List <JToken> tokensToDelete = null;

            List <string> loopProperties = null;
            JArray        arrayToForm    = null;
            JObject       dictToForm     = null;
            List <JToken> tokenToForm    = null;
            List <JToken> tokensToAdd    = null;

            bool isLoop = false;
            bool isBulk = false;

            foreach (JToken childToken in tokens)
            {
                if (childToken.Type == JTokenType.Array && (parentToken as JProperty)?.Name.Trim() != "#")
                {
                    JArray arrayToken = childToken as JArray;

                    List <object> itemsToAdd = new List <object>();

                    foreach (JToken arrEl in childToken.Children())
                    {
                        object itemToAdd = arrEl.Value <JToken>();

                        if (arrEl.Type == JTokenType.String && arrEl.ToString().Trim().StartsWith("#"))
                        {
                            object value = ParseFunction(arrEl.ToString(), inputJson, parentArray, currentArrayToken, localContext);
                            itemToAdd = value;
                        }

                        itemsToAdd.Add(itemToAdd);
                    }

                    arrayToken.RemoveAll();

                    foreach (object itemToAdd in itemsToAdd)
                    {
                        if (itemToAdd is Array)
                        {
                            foreach (var item in itemToAdd as Array)
                            {
                                arrayToken.Add(Utilities.GetNestedData(item));
                            }
                        }
                        else
                        {
                            arrayToken.Add(JToken.FromObject(itemToAdd));
                        }
                    }
                }

                if (childToken.Type == JTokenType.Property)
                {
                    JProperty property = childToken as JProperty;

                    if (property.Name != null && property.Name == "#" && property.Value.Type == JTokenType.Array)
                    {
                        JArray values = property.Value as JArray;

                        JEnumerable <JToken> arrayValues = values.Children();

                        foreach (JToken arrayValue in arrayValues)
                        {
                            if (arrayValue.Type == JTokenType.String &&
                                ExpressionHelper.TryParseFunctionNameAndArguments(
                                    arrayValue.Value <string>().Trim(), out string functionName, out string arguments))
                            {
                                if (functionName == "copy")
                                {
                                    if (selectedTokens == null)
                                    {
                                        selectedTokens = new List <JToken>();
                                    }

                                    selectedTokens.Add(Copy(arguments, inputJson, parentArray, currentArrayToken, localContext));
                                }
                                else if (functionName == "replace")
                                {
                                    if (tokensToReplace == null)
                                    {
                                        tokensToReplace = new Dictionary <string, JToken>();
                                    }

                                    var replaceResult = Replace(arguments, inputJson, parentArray, currentArrayToken, localContext);
                                    tokensToReplace.Add(replaceResult.Key, replaceResult.Value);
                                }
                                else if (functionName == "delete")
                                {
                                    if (tokensToDelete == null)
                                    {
                                        tokensToDelete = new List <JToken>();
                                    }

                                    tokensToDelete.Add(Delete(arguments, inputJson, parentArray, currentArrayToken, localContext));
                                }
                            }
                        }

                        isBulk = true;
                    }

                    if (property.Name != null && property.Value.ToString().Trim().StartsWith("#") &&
                        !property.Name.Contains("#eval") && !property.Name.Contains("#ifgroup") &&
                        !property.Name.Contains("#loop"))
                    {
                        object newValue = ParseFunction(property.Value.ToString(), inputJson, parentArray, currentArrayToken, localContext);
                        property.Value = GetToken(newValue, localContext);
                    }

                    /* For looping*/
                    isLoop = false;

                    if (property.Name != null && property.Name.Contains("#eval"))
                    {
                        ExpressionHelper.TryParseFunctionNameAndArguments(property.Name, out string functionName, out string functionString);
                        object functionResult = ParseFunction(functionString, inputJson, parentArray, currentArrayToken, localContext);

                        JProperty clonedProperty = new JProperty(functionResult.ToString(), ParseFunction(property.Value.ToString(), inputJson, parentArray, currentArrayToken, localContext));

                        if (loopProperties == null)
                        {
                            loopProperties = new List <string>();
                        }

                        loopProperties.Add(property.Name);

                        if (tokensToAdd == null)
                        {
                            tokensToAdd = new List <JToken>
                            {
                                clonedProperty
                            };
                        }
                    }

                    if (property.Name != null && property.Name.Contains("#ifgroup"))
                    {
                        ExpressionHelper.TryParseFunctionNameAndArguments(property.Name, out string functionName, out string functionString);
                        object functionResult = ParseFunction(functionString, inputJson, parentArray, currentArrayToken, localContext);
                        bool   result         = false;

                        try
                        {
                            result = (bool)ReflectionHelper.GetTypedValue(typeof(bool), functionResult, GetEvaluationMode(localContext));
                        }
                        catch
                        {
                            if (IsStrictMode(localContext))
                            {
                                throw;
                            }
                            result = false;
                        }

                        if (result == true)
                        {
                            if (loopProperties == null)
                            {
                                loopProperties = new List <string>();
                            }

                            loopProperties.Add(property.Name);

                            RecursiveEvaluate(childToken, inputJson, parentArray, currentArrayToken, localContext);

                            if (tokenToForm == null)
                            {
                                tokenToForm = new List <JToken>();
                            }

                            foreach (JToken grandChildToken in childToken.Children())
                            {
                                tokenToForm.Add(grandChildToken.DeepClone());
                            }
                        }
                        else
                        {
                            if (loopProperties == null)
                            {
                                loopProperties = new List <string>();
                            }

                            loopProperties.Add(property.Name);
                        }

                        isLoop = true;
                    }

                    if (property.Name != null && property.Name.Contains("#loop"))
                    {
                        ExpressionHelper.TryParseFunctionNameAndArguments(property.Name, out string functionName, out string arguments);
                        var token = currentArrayToken != null && functionName == "loopwithincontext" ? currentArrayToken : GetInputToken(localContext);

                        var strArrayToken = ParseArgument(inputJson, parentArray, currentArrayToken, arguments, localContext) as string;

                        bool   isDictionary = false;
                        JToken arrayToken;
                        try
                        {
                            arrayToken = token.SelectToken(strArrayToken);
                            if (Regex.IsMatch(strArrayToken ?? string.Empty, "\\[.+\\]$") && arrayToken.Type != JTokenType.Array)
                            {
                                arrayToken = new JArray(arrayToken);
                            }

                            if (arrayToken is IDictionary <string, JToken> dict) //JObject is a dictionary
                            {
                                isDictionary = true;
                                JArray arr = new JArray();
                                foreach (var item in dict)
                                {
                                    arr.Add(new JObject {
                                        { item.Key, item.Value }
                                    });
                                }

                                arrayToken = arr;
                            }
                        }
                        catch
                        {
                            var multipleTokens = token.SelectTokens(strArrayToken);
                            arrayToken = new JArray(multipleTokens);
                        }

                        JArray array = arrayToken as JArray;
                        if (array != null)
                        {
                            using (IEnumerator <JToken> elements = array.GetEnumerator())
                            {
                                arrayToForm = new JArray();
                                if (!isDictionary)
                                {
                                    while (elements.MoveNext())
                                    {
                                        JToken clonedToken = childToken.DeepClone();

                                        RecursiveEvaluate(clonedToken, inputJson, array, elements.Current, localContext);

                                        foreach (JToken replacedProperty in clonedToken.Children())
                                        {
                                            arrayToForm.Add(replacedProperty);
                                        }
                                    }
                                }
                                else
                                {
                                    dictToForm = new JObject();
                                    while (elements.MoveNext())
                                    {
                                        JToken clonedToken = childToken.DeepClone();
                                        RecursiveEvaluate(clonedToken, inputJson, array, elements.Current, localContext);
                                        foreach (JToken replacedProperty in clonedToken.Children().Select(t => t.First))
                                        {
                                            dictToForm.Add(replacedProperty);
                                        }
                                    }
                                }
                            }
                        }

                        if (loopProperties == null)
                        {
                            loopProperties = new List <string>();
                        }

                        loopProperties.Add(property.Name);
                        isLoop = true;
                    }
                    /*End looping */
                }

                if (childToken.Type == JTokenType.String && childToken.Value <string>().Trim().StartsWith("#") &&
                    parentArray != null && currentArrayToken != null)
                {
                    object newValue = ParseFunction(childToken.Value <string>(), inputJson, parentArray, currentArrayToken, localContext);

                    JToken replaceToken = GetToken(newValue, localContext);
                    childToken.Replace(replaceToken);
                }

                if (!isLoop && !isBulk)
                {
                    RecursiveEvaluate(childToken, inputJson, parentArray, currentArrayToken, localContext);
                }
            }

            if (selectedTokens != null)
            {
                foreach (JToken selectedToken in selectedTokens)
                {
                    if (selectedToken != null)
                    {
                        JEnumerable <JToken> copyChildren = selectedToken.Children();

                        foreach (JToken copyChild in copyChildren)
                        {
                            JProperty property = copyChild as JProperty;

                            (parentToken as JObject).Add(property.Name, property.Value);
                        }
                    }
                }
            }

            if (tokensToReplace != null)
            {
                foreach (KeyValuePair <string, JToken> tokenToReplace in tokensToReplace)
                {
                    JToken selectedToken = (parentToken as JObject).SelectToken(tokenToReplace.Key);
                    selectedToken.Replace(tokenToReplace.Value);
                }
            }

            if (tokensToDelete != null)
            {
                foreach (string selectedToken in tokensToDelete)
                {
                    JToken tokenToRemove = parentToken.SelectToken(selectedToken);

                    if (tokenToRemove != null)
                    {
                        tokenToRemove.Ancestors().First().Remove();
                    }
                }
            }
            if (tokensToAdd != null)
            {
                foreach (JToken token in tokensToAdd)
                {
                    (parentToken as JObject).Add((token as JProperty).Name, (token as JProperty).Value);
                }
            }

            if (tokenToForm != null)
            {
                foreach (JToken token in tokenToForm)
                {
                    foreach (JProperty childToken in token.Children())
                    {
                        (parentToken as JObject).Add(childToken.Name, childToken.Value);
                    }
                }
            }
            if (parentToken is JObject jObject)
            {
                jObject.Remove("#");
            }

            if (loopProperties != null)
            {
                foreach (string propertyToDelete in loopProperties)
                {
                    if (dictToForm == null && arrayToForm == null && parentToken.Count() <= 1)
                    {
                        parentToken.Replace(JValue.CreateNull());
                    }
                    else
                    {
                        (parentToken as JObject).Remove(propertyToDelete);
                    }
                }
            }

            if (dictToForm != null)
            {
                parentToken.Replace(dictToForm);
            }
            else if (arrayToForm != null)
            {
                if (parentToken.Parent != null && parentToken.Parent is JArray arr)
                {
                    foreach (var item in arrayToForm)
                    {
                        arr.Add(item);
                    }
                    if (!parentToken.HasValues)
                    {
                        var tmp = parentToken;
                        parentToken = arr;
                        tmp.Remove();
                    }
                }
                else if (parentToken.Parent != null)
                {
                    parentToken.Replace(arrayToForm);
                }
            }
        }
Beispiel #3
0
        private static void RecursiveEvaluate(JToken parentToken, string inputJson, JArray parentArray, JToken currentArrayToken, JUSTContext localContext)
        {
            if (parentToken == null)
            {
                return;
            }

            JEnumerable <JToken> tokens = parentToken.Children();

            List <JToken> selectedTokens = null;
            Dictionary <string, JToken> tokensToReplace = null;
            List <JToken> tokensToDelete = null;

            List <string> loopProperties = null;
            JArray        arrayToForm    = null;
            List <JToken> tokenToForm    = null;
            List <JToken> tokensToAdd    = null;

            bool isLoop = false;

            foreach (JToken childToken in tokens)
            {
                if (childToken.Type == JTokenType.Array && (parentToken as JProperty).Name.Trim() != "#")
                {
                    JArray arrayToken = childToken as JArray;

                    List <object> itemsToAdd = new List <object>();

                    foreach (JToken arrEl in childToken.Children())
                    {
                        object itemToAdd = arrEl.Value <JToken>();

                        if (arrEl.Type == JTokenType.String && arrEl.ToString().Trim().StartsWith("#"))
                        {
                            object value = ParseFunction(arrEl.ToString(), inputJson, parentArray, currentArrayToken, localContext);
                            itemToAdd = value;
                        }

                        itemsToAdd.Add(itemToAdd);
                    }

                    arrayToken.RemoveAll();

                    foreach (object itemToAdd in itemsToAdd)
                    {
                        arrayToken.Add(itemToAdd);
                    }
                }

                if (childToken.Type == JTokenType.Property)
                {
                    JProperty property = childToken as JProperty;

                    if (property.Name != null && property.Name == "#" && property.Value.Type == JTokenType.Array)
                    {
                        JArray values = property.Value as JArray;

                        JEnumerable <JToken> arrayValues = values.Children();

                        foreach (JToken arrayValue in arrayValues)
                        {
                            if (arrayValue.Type == JTokenType.String &&
                                ExpressionHelper.TryParseFunctionNameAndArguments(
                                    arrayValue.Value <string>().Trim(), out string functionName, out string arguments))
                            {
                                if (functionName == "copy")
                                {
                                    if (selectedTokens == null)
                                    {
                                        selectedTokens = new List <JToken>();
                                    }

                                    selectedTokens.Add(Copy(arguments, inputJson, localContext));
                                }
                                else if (functionName == "replace")
                                {
                                    if (tokensToReplace == null)
                                    {
                                        tokensToReplace = new Dictionary <string, JToken>();
                                    }

                                    var replaceResult = Replace(arguments, inputJson, localContext);
                                    tokensToReplace.Add(replaceResult.Key, replaceResult.Value);
                                }
                                else if (functionName == "delete")
                                {
                                    if (tokensToDelete == null)
                                    {
                                        tokensToDelete = new List <JToken>();
                                    }

                                    tokensToDelete.Add(Delete(arguments, inputJson, localContext));
                                }
                            }
                        }
                    }

                    if (property.Name != null && property.Value.ToString().Trim().StartsWith("#") &&
                        !property.Name.Contains("#eval") && !property.Name.Contains("#ifgroup") &&
                        !property.Name.Contains("#loop"))
                    {
                        object newValue = ParseFunction(property.Value.ToString(), inputJson, parentArray, currentArrayToken, localContext);
                        property.Value = GetToken(newValue, localContext);
                    }

                    /* For looping*/
                    isLoop = false;

                    if (property.Name != null && property.Name.Contains("#eval"))
                    {
                        ExpressionHelper.TryParseFunctionNameAndArguments(property.Name, out string functionName, out string functionString);
                        object functionResult = ParseFunction(functionString, inputJson, null, null, localContext);

                        JProperty clonedProperty = new JProperty(functionResult.ToString(), property.Value);

                        if (loopProperties == null)
                        {
                            loopProperties = new List <string>();
                        }

                        loopProperties.Add(property.Name);

                        if (tokensToAdd == null)
                        {
                            tokensToAdd = new List <JToken>
                            {
                                clonedProperty
                            };
                        }
                    }

                    if (property.Name != null && property.Name.Contains("#ifgroup"))
                    {
                        ExpressionHelper.TryParseFunctionNameAndArguments(property.Name, out string functionName, out string functionString);
                        object functionResult = ParseFunction(functionString, inputJson, null, null, localContext);
                        bool   result         = false;

                        try
                        {
                            result = (bool)ReflectionHelper.GetTypedValue(typeof(bool), functionResult, GetEvaluationMode(localContext));
                        }
                        catch
                        {
                            if (IsStrictMode(localContext))
                            {
                                throw;
                            }
                            result = false;
                        }

                        if (result == true)
                        {
                            if (loopProperties == null)
                            {
                                loopProperties = new List <string>();
                            }

                            loopProperties.Add(property.Name);

                            RecursiveEvaluate(childToken, inputJson, parentArray, currentArrayToken, localContext);

                            if (tokenToForm == null)
                            {
                                tokenToForm = new List <JToken>();
                            }

                            foreach (JToken grandChildToken in childToken.Children())
                            {
                                tokenToForm.Add(grandChildToken.DeepClone());
                            }
                        }
                        else
                        {
                            if (loopProperties == null)
                            {
                                loopProperties = new List <string>();
                            }

                            loopProperties.Add(property.Name);
                        }

                        isLoop = true;
                    }

                    if (property.Name != null && property.Name.Contains("#loop"))
                    {
                        string strArrayToken = property.Name.Substring(6, property.Name.Length - 7);

                        var jsonToLoad = inputJson;
                        if (currentArrayToken != null && property.Name.Contains("#loopwithincontext"))
                        {
                            strArrayToken = property.Name.Substring(19, property.Name.Length - 20);
                            jsonToLoad    = JsonConvert.SerializeObject(currentArrayToken);
                        }

                        JToken token      = JsonConvert.DeserializeObject <JObject>(jsonToLoad);
                        JToken arrayToken = null;
                        if (strArrayToken.Contains("#"))
                        {
                            int    sIndex = strArrayToken.IndexOf("#");
                            string sub1   = strArrayToken.Substring(0, sIndex);

                            int indexOfENdFubction = GetIndexOfFunctionEnd(strArrayToken);

                            if (indexOfENdFubction > sIndex && sIndex > 0)
                            {
                                string sub2 = strArrayToken.Substring(indexOfENdFubction + 1, strArrayToken.Length - indexOfENdFubction - 1);

                                string functionResult = ParseFunction(strArrayToken.Substring(sIndex, indexOfENdFubction - sIndex + 1), inputJson, parentArray, currentArrayToken, localContext).ToString();

                                strArrayToken = sub1 + functionResult + sub2;
                            }
                        }
                        try
                        {
                            arrayToken = token.SelectToken(strArrayToken);

                            if (arrayToken is JObject)
                            {
                                arrayToken = new JArray(arrayToken);
                            }
                        }
                        catch
                        {
                            var multipleTokens = token.SelectTokens(strArrayToken);

                            arrayToken = new JArray(multipleTokens);
                        }

                        if (arrayToken == null)
                        {
                            arrayToForm = new JArray();
                        }
                        else
                        {
                            JArray array = (JArray)arrayToken;

                            IEnumerator <JToken> elements = array.GetEnumerator();

                            while (elements.MoveNext())
                            {
                                if (arrayToForm == null)
                                {
                                    arrayToForm = new JArray();
                                }

                                JToken clonedToken = childToken.DeepClone();

                                RecursiveEvaluate(clonedToken, inputJson, array, elements.Current, localContext);

                                foreach (JToken replacedProperty in clonedToken.Children())
                                {
                                    arrayToForm.Add(replacedProperty);
                                }
                            }
                        }
                        if (loopProperties == null)
                        {
                            loopProperties = new List <string>();
                        }

                        loopProperties.Add(property.Name);
                        isLoop = true;
                    }
                    /*End looping */
                }

                if (childToken.Type == JTokenType.String && childToken.Value <string>().Trim().StartsWith("#") &&
                    parentArray != null && currentArrayToken != null)
                {
                    object newValue = ParseFunction(childToken.Value <string>(), inputJson, parentArray, currentArrayToken, localContext);

                    JToken replaceToken = GetToken(newValue, localContext);
                    childToken.Replace(replaceToken);
                }

                if (!isLoop)
                {
                    RecursiveEvaluate(childToken, inputJson, parentArray, currentArrayToken, localContext);
                }
            }

            if (selectedTokens != null)
            {
                foreach (JToken selectedToken in selectedTokens)
                {
                    if (selectedToken != null)
                    {
                        JEnumerable <JToken> copyChildren = selectedToken.Children();

                        foreach (JToken copyChild in copyChildren)
                        {
                            JProperty property = copyChild as JProperty;

                            (parentToken as JObject).Add(property.Name, property.Value);
                        }
                    }
                }
            }

            if (tokensToReplace != null)
            {
                foreach (KeyValuePair <string, JToken> tokenToReplace in tokensToReplace)
                {
                    JToken selectedToken = (parentToken as JObject).SelectToken(tokenToReplace.Key);

                    if (selectedToken != null && selectedToken is JObject)
                    {
                        JObject selectedObject = selectedToken as JObject;
                        selectedObject.RemoveAll();

                        JEnumerable <JToken> copyChildren = tokenToReplace.Value.Children();

                        foreach (JToken copyChild in copyChildren)
                        {
                            JProperty property = copyChild as JProperty;
                            selectedObject.Add(property.Name, property.Value);
                        }
                    }
                    if (selectedToken != null && selectedToken is JValue)
                    {
                        JValue selectedObject = selectedToken as JValue;
                        selectedObject.Value = tokenToReplace.Value.ToString();
                    }
                }
            }

            if (tokensToDelete != null)
            {
                foreach (string selectedToken in tokensToDelete)
                {
                    JToken tokenToRemove = parentToken.SelectToken(selectedToken);

                    if (tokenToRemove != null)
                    {
                        tokenToRemove.Ancestors().First().Remove();
                    }
                }
            }
            if (tokensToAdd != null)
            {
                foreach (JToken token in tokensToAdd)
                {
                    (parentToken as JObject).Add((token as JProperty).Name, (token as JProperty).Value);
                }
            }

            if (tokenToForm != null)
            {
                foreach (JToken token in tokenToForm)
                {
                    foreach (JProperty childToken in token.Children())
                    {
                        (parentToken as JObject).Add(childToken.Name, childToken.Value);
                    }
                }
            }
            if (parentToken is JObject)
            {
                (parentToken as JObject).Remove("#");
            }

            if (loopProperties != null)
            {
                foreach (string propertyToDelete in loopProperties)
                {
                    (parentToken as JObject).Remove(propertyToDelete);
                }
            }
            if (arrayToForm != null)
            {
                parentToken.Replace(arrayToForm);
            }
        }