XmlDocument ResolveXml(ref List <object> forEachParms, object parentExitData, Dictionary <string, ParameterInfo> globalParamSets)
        {
            string context = "ResolveXml";
            string errData = __nodata;

            try
            {
                XmlDocument parms = null;

                if (HasInheritedValues)
                {
                    context = "InheritedValues=>Clone";
                    errData = InheritedValues.GetType().ToString();
                    parms   = (XmlDocument)((XmlDocument)((ParameterInfo)InheritedValues).Values).Clone();
                }

                if (HasUri)
                {
                    context = "Uri=>Fetch";
                    try { errData = new Uri(Uri).ToString(); } catch { errData = Uri.ToString(); }

                    string uriContent = WebRequestClient.GetString(Uri);
                    context = "Uri=>Fetch, LoadXml";
                    errData = uriContent;
                    XmlDocument uriXml = new XmlDocument();
                    uriXml.LoadXml(uriContent);

                    context = parms != null ? "Merge->Inherited" : "Assign to parms";
                    context = $"Uri=>{context}";
                    errData = XmlHelpers.Serialize <XmlDocument>(uriXml);
                    if (parms != null)
                    {
                        XmlHelpers.Merge(ref parms, uriXml);
                    }
                    else
                    {
                        parms = uriXml;
                    }
                }

                //merge parms
                if (HasValues)
                {
                    context = "HasValues=>LoadXml";
                    errData = Values.ToString();
                    XmlDocument values = new XmlDocument();
                    values.LoadXml(Values.ToString());

                    context = parms != null ? "Merge->Inherited+Uri+Values" : "Assign to parms";
                    context = $"Uri=>{context}";
                    errData = XmlHelpers.Serialize <XmlDocument>(values);
                    if (parms != null)
                    {
                        XmlHelpers.Merge(ref parms, values);
                    }
                    else
                    {
                        parms = values;
                    }
                }


                if (parms == null)
                {
                    parms = new XmlDocument();
                }


                //kv_replace
                if (HasDynamic)
                {
                    context = "HasDynamic=>Merge->Inherited+Uri+Values+Dynamic";
                    try { errData = YamlHelpers.Serialize(_dynamicData); } catch { errData = __nodata; }   //YamlHelpers not a mistake, used it on purpose for easy to read error data
                    XmlHelpers.Merge(ref parms, Dynamic, _dynamicData);
                }

                if (HasParentExitData && parentExitData != null)
                {
                    context = "ParentExitData=>Init Xml Source";
                    errData = parentExitData.GetType().ToString();

                    XmlDocument xd = new XmlDocument();
                    if (parentExitData is XmlNode)
                    {
                        xd.InnerXml = ((XmlNode)parentExitData).OuterXml;
                    }
                    else if (parentExitData is XmlNode[])
                    {
                        xd.InnerXml = ((XmlNode[])parentExitData)[0].OuterXml;
                    }
                    else if (parentExitData is string)
                    {
                        xd.InnerXml = (string)parentExitData;
                    }
                    else
                    {
                        xd = (XmlDocument)parentExitData;
                    }

                    context = "ParentExitData=>Merge->Inhetited+Uri+Values+Dynamic+ParentExitData";
                    errData = XmlHelpers.Serialize <XmlDocument>(xd);
                    XmlHelpers.Merge(ref parms, ParentExitData, ref xd);
                }

                if (HasForEach && parms != null)
                {
                    //assemble ForEach variables
                    if (ForEach.HasParameterSourceItems)
                    {
                        context = "ForEach=>HasParameterSourceItems";
                        errData = null;
                        XmlHelpers.SelectForEachFromValues(ForEach.ParameterSourceItems, ref parms, globalParamSets, parentExitData);
                    }

                    //expand ForEach variables
                    context = "ForEach=>ExpandForEach";
                    try { errData = XmlHelpers.Serialize <XmlDocument>(parms); } catch { errData = __nodata; }
                    forEachParms = XmlHelpers.ExpandForEachAndApplyPatchValues(ref parms, ForEach);
                }


                return(parms);
            }
            catch (Exception ex)
            {
                throw new Exception(GetResolveExceptionMessage(context, errData), ex);
            }
        }