/// <summary>
        /// Method which executes the BRE Policy which is configured using the config and resolver connection string
        /// </summary>
        /// <param name="config">string containing name, value property values</param>
        /// <param name="resolver">Resolver connection string</param>
        /// <param name="message">Xml document containing the message to pass to the BRE policies if configured properly</param>
        /// <param name="resolution">Resolution object</param>
        /// <param name="bre">BRE Descriptor object</param>
        /// <param name="ctxtValues">Dictionary collection of BizTalk Message Context property value pairs</param>
        /// <param name="pCtxt">BizTalk Pipeline Context</param>
        /// <param name="baseMsg">BizTalk BaseMessage</param>
        /// <returns>Resolver Dictionary Collection containing resolved entries, such as itinerary name, map name, and endpoint address resolution values</returns>
        private static Dictionary <string, string> ResolveRules(string config, string resolver, XmlDocument message, Resolution resolution, BRE bre, Dictionary <string, string> ctxtValues, IPipelineContext pCtxt, ref IBaseMessage baseMsg)
        {
            Dictionary <string, string> dictionary3;
            int    num    = 0;
            int    num2   = 0;
            Policy policy = null;
            Dictionary <string, string> dictionary = null;

            string[]         strArray      = null;
            object[]         objArray      = null;
            TypedXmlDocument document      = null;
            ItineraryFact    itineraryInfo = new ItineraryFact();

            string documentSpecNameField = "Microsoft.Practices.ESB.ResolveProviderMessage";
            Dictionary <string, string> resolverDictionary = new Dictionary <string, string>();

            if (!resolver.Contains(@":\"))
            {
                resolver = resolver + @":\";
            }
            try
            {
                EventLogger.Write("Resolution strong name is {0}.", new object[] { resolution.DocumentSpecNameField });
                if (!string.IsNullOrEmpty(resolution.DocumentSpecNameField) && bre.recognizeMessageFormat)
                {
                    int index = resolution.DocumentSpecNameField.IndexOf(",", StringComparison.CurrentCultureIgnoreCase);
                    if ((index > 0) && (index < resolution.DocumentSpecNameField.Length))
                    {
                        documentSpecNameField = resolution.DocumentSpecNameField.Substring(0, index);
                    }
                    else
                    {
                        documentSpecNameField = resolution.DocumentSpecNameField;
                    }
                }


                // add root node as non promoted value for purpose of using with Orchestrations if needed
                if (ctxtValues == null)
                {
                    ctxtValues = new Dictionary <string, string>();
                }
                ctxtValues.Add("Microsoft.Practices.ESB.ResolveProviderMessage#RootNode", message.DocumentElement.LocalName.ToUpperInvariant());

                MessageContextFactRetriever customFactRetriever = new MessageContextFactRetriever(ctxtValues);

                EventLogger.Write("DocType for typed xml document is {0}.", new object[] { documentSpecNameField });
                if (!string.IsNullOrEmpty(bre.version))
                {
                    strArray = bre.version.Split(".".ToCharArray());
                    if (strArray != null)
                    {
                        num  = Convert.ToInt16(strArray[0], NumberFormatInfo.CurrentInfo);
                        num2 = Convert.ToInt16(strArray[1], NumberFormatInfo.CurrentInfo);
                    }
                }
                if (bre.useMsg)
                {
                    EventLogger.Write("Xml document Content is {0}.", message.OuterXml);
                    objArray = new object[4];
                    document = new TypedXmlDocument(documentSpecNameField, message);

                    objArray[0] = resolution;
                    objArray[1] = document;
                    objArray[2] = itineraryInfo;
                    objArray[3] = customFactRetriever;
                }
                else
                {
                    objArray = new object[] { resolution, itineraryInfo, customFactRetriever };
                }

                bool   useDebugInterceptor = false;
                string outputPath          = string.Empty;
                if (bre.useDebugInterceptorSpecified)
                {
                    useDebugInterceptor = bre.useDebugInterceptor;
                    outputPath          = bre.debugOutputPath;
                    policyExecutor      = new PolicyExecutor(useDebugInterceptor, outputPath);
                }
                else
                {
                    policyExecutor = new PolicyExecutor(false, string.Empty);
                }

                // Check to see if we need to use the Policy Broker
                if (bre.usePolicyBrokerSpecified)
                {
                    if (bre.usePolicyBroker)
                    {
                        PolicyBroker broker = new PolicyBroker(useDebugInterceptor, outputPath);
                        PolicyBrokerInfoCollection _policyInfos = broker.GetPolicies(message, resolution, bre.policy, itineraryInfo, customFactRetriever, num, num2);
                        foreach (var policyBrokerInfo in _policyInfos.PolicyInfos)
                        {
                            var policyInfo       = policyBrokerInfo.Value;
                            int foundPolicyMajor = 0;
                            int foundPolicyMinor = 0;
                            strArray = policyInfo.Version.Split(".".ToCharArray());
                            if (strArray != null)
                            {
                                foundPolicyMajor = Convert.ToInt16(strArray[0], NumberFormatInfo.CurrentInfo);
                                foundPolicyMinor = Convert.ToInt16(strArray[1], NumberFormatInfo.CurrentInfo);
                            }
                            policyExecutor.ExecutePolicy(policyInfo.PolicyName, objArray, foundPolicyMajor, foundPolicyMinor);
                        }
                    }
                    else
                    {
                        // don't use policy broker
                        policyExecutor.ExecutePolicy(bre.policy, objArray, num, num2);
                    }
                }
                else
                {
                    // don't use policy broker
                    policyExecutor.ExecutePolicy(bre.policy, objArray, num, num2);
                }

                if (objArray[0] == null)
                {
                    throw new ResolveException("Resolution is not configured correctly after applying BRE Custom Resolver;\nPlease check the Business Rule Policy");
                }

                // Check for Itinerary fact values
                SetAllResolutionDictionaryEntries(objArray, resolverDictionary, bre);
                dictionary3 = resolverDictionary;

                if (bre.useMsg)
                {
                    TypedXmlDocument doc = (TypedXmlDocument)objArray[1];
                    dictionary3.Add("message", doc.Document.OuterXml);

                    if (bre.useMsgCtxt)
                    {
                        MessageContextFactRetriever customRetriever = (MessageContextFactRetriever)objArray[3];
                        dictionary3.Add("contextValues", GetContextValuesString(customRetriever.GetDictionaryCollection()));

                        // Update the context properties
                        UpdateContextProperties(customRetriever, bre, pCtxt, ref baseMsg);
                    }

                    // Modify the Current Message in pipeline context
                    UpdateMessage(doc.Document.OuterXml, pCtxt, ref baseMsg);
                }
                else
                {
                    if (bre.useMsgCtxt)
                    {
                        MessageContextFactRetriever customRetriever = (MessageContextFactRetriever)objArray[2];
                        dictionary3.Add("contextValues", GetContextValuesString(customRetriever.GetDictionaryCollection()));

                        // Update the context properties
                        UpdateContextProperties(customRetriever, bre, pCtxt, ref baseMsg);
                    }
                }
            }
            catch (Exception exception)
            {
                EventLogger.Write(MethodBase.GetCurrentMethod(), exception);
                throw;
            }
            finally
            {
                if (objArray != null)
                {
                    objArray = null;
                }
                if (document != null)
                {
                    document = null;
                }
                if (resolution != null)
                {
                    resolution = null;
                }
                if (bre != null)
                {
                    bre = null;
                }
                if (strArray != null)
                {
                    strArray = null;
                }
                if (policy != null)
                {
                    policy.Dispose();
                    policy = null;
                }
                if (dictionary != null)
                {
                    dictionary.Clear();
                    dictionary = null;
                }
                if (resolverDictionary != null)
                {
                    resolverDictionary = null;
                }
                if (ctxtValues != null)
                {
                    ctxtValues = null;
                }
            }
            return(dictionary3);
        }
        /// <summary>
        /// Updates the BizTalk BaseMessage and Message Context with any new or modified values from the executed BRE Policies.
        /// </summary>
        /// <param name="msgCtxt">BizTalk BaseMessage Context value collection to update</param>
        /// <param name="bre">BRE Descriptor with possible values to read for updating the Message context</param>
        /// <param name="pCtxt">PipelineContext</param>
        /// <param name="baseMsg">BizTalk BaseMessage to update</param>
        private static void UpdateContextProperties(MessageContextFactRetriever msgCtxt, BRE bre, IPipelineContext pCtxt, ref IBaseMessage baseMsg)
        {
            try
            {
                if (pCtxt == null || baseMsg == null)
                {
                    return;
                }
                IBaseMessageContext baseMsgCtxt = baseMsg.Context;
                foreach (var updatedCtxt in msgCtxt.GetDictionaryCollection())
                {
                    string[] NameNameSpaceValues = updatedCtxt.Key.Split('#');

                    // no need to check for old values just overwrite and add
                    // Check to see if we need to promote it
                    string name            = NameNameSpaceValues[1];
                    bool   shouldPromote   = name.Contains("!");
                    bool   isDistinguished = name.Contains("/");

                    string namesp = NameNameSpaceValues[0];

                    // check to determine if we should promote and not distinguished
                    if (shouldPromote && !isDistinguished)
                    {
                        string correctName = name;

                        // remove ! char from key name before promoting
                        if (shouldPromote)
                        {
                            correctName = name.Substring(0, name.Length - 1);
                        }

                        // however check to see if already promoted or not
                        bool isAlreadyPromoted = false;
                        var  ovalue            = baseMsgCtxt.Read(correctName, namesp);
                        if (ovalue != null)
                        {
                            isAlreadyPromoted = baseMsgCtxt.IsPromoted(correctName, namesp);
                        }

                        if (ovalue != null && isAlreadyPromoted)
                        {
                            // we need to remove and re - promote
                            baseMsgCtxt.Write(correctName, namesp, null);
                            baseMsgCtxt.Promote(correctName, namesp, null);
                            baseMsgCtxt.Promote(correctName, namesp, updatedCtxt.Value);
                        }
                        else
                        {
                            // it's not already promoted and we should promote if we can,
                            // this assumes there is a valid property schema, name, and data type associated with it for promotion validation...
                            // dangerous operation which could cause cyclic loop by re-promoting a property that was slated to be demoted *wasPromote*...
                            if (bre.useRepromotionSpecified)
                            {
                                if (bre.useRepromotion)
                                {
                                    try
                                    {
                                        baseMsgCtxt.Write(correctName, namesp, null);
                                        baseMsgCtxt.Promote(correctName, namesp, null);
                                        baseMsgCtxt.Promote(correctName, namesp, updatedCtxt.Value);
                                    }
                                    catch (Exception ex)
                                    {
                                        EventLogger.LogMessage(
                                            string.Format(
                                                "Namespace: {0}\nName: {1}\n caused an exception:\n{2}\nThis item was not promoted.",
                                                namesp, correctName, ex.Message), EventLogEntryType.Error, 1000);
                                    }
                                }
                            }
                        }
                    }
                    else if (shouldPromote && isDistinguished)
                    {
                        // can't promote a distinguished field that contains a "/" in it's name, there's no way for BizTalk to validate it using normal BizTalk Property Schemas...
                        // do nothing.
                    }
                    else if (isDistinguished)
                    {
                        // We don't need to promote it, only write it (Distinguished)
                        // we need to remove and re-write it
                        baseMsgCtxt.Write(name, namesp, null);
                        baseMsgCtxt.Write(name, namesp, updatedCtxt.Value);
                    }
                    //else niether promote nore write so do nothing...
                }
                pCtxt.ResourceTracker.AddResource(baseMsgCtxt);
            }
            catch (Exception ex)
            {
                EventLog.WriteEntry("BRE_ResolverProvider::UpdateContextProperties", ex.ToString(),
                                    EventLogEntryType.Error, 10000);
                throw;
            }
        }