void AQSubscriberKEUIRequest_OnMessageReceived(string message)
        {
            try
            {
                lock (_mqLock)
                {
                    AddEvent("Received KEUI Request " + GetDateStamp());
                    StoreEventData(_activeMQSettings.TopicNameKEUIRequest, message);

                    HtmlAgilityPack.XmlDocument xmlDoc = new HtmlAgilityPack.XmlDocument();
                    xmlDoc.LoadXml(message);
                    var eventDataNode = xmlDoc.DocumentNode.SelectSingleNode("//ns1:eventData");
                    var requestNode = xmlDoc.DocumentNode.SelectSingleNode("//ns1:eventData/s1:keuiRequest");
                    if (requestNode == null) { AddEventAndLog("The KEUI request event did not contain //ns1:eventData/s1:keuiRequest node. Ignoring request"); return; }

                    string requestType = requestNode.SelectSingleNode("./s1:requestType").InnerText;
                    string publishTopic = requestNode.SelectSingleNode("./s1:publishResponseOnTopic") != null ? requestNode.SelectSingleNode("./s1:publishResponseOnTopic").InnerText.DecodeXMLString() : _activeMQSettings.TopicNameKEUIPublishResponse;

                    string keuiResponseData = null;

                    requestType = requestType.Trim();	// make sure we ignore the newlines and spaces
                    AddEvent("Request type: " + requestType);
                    if (requestType == "GetSuggestions")
                    {
                        var queryNode = requestNode.SelectSingleNode("./s1:requestData/query");
                        string prefix = queryNode.GetAttributeValue("prefix", "");
                        string suggestionTypes = queryNode.GetAttributeValue("suggestionTypes", "");
                        suggestionTypes = suggestionTypes.ToLower();

                        if (string.IsNullOrEmpty(prefix))
                        {
                            AddEventAndLog("Unable to provide suggestions. No prefix was specified in the event.");
                            return;
                        }
                        prefix = GenLib.Text.Text.ReplaceUnicodeCharsWithAscii(prefix);
                        keuiResponseData = "<suggestions>";
                        if (string.IsNullOrEmpty(suggestionTypes) || suggestionTypes.Contains("concepts"))
                        {
                            List<Tuple<string, string>> suggestionsConcepts = _keui.SuggestConceptsForPrefix(prefix);
                            foreach (var sugg in suggestionsConcepts)
                                keuiResponseData += String.Format("<concept label=\"{0}\" uri=\"{1}\" />", sugg.Item1.EncodeXMLString(), sugg.Item2.EncodeXMLString());
                        }
                        if (string.IsNullOrEmpty(suggestionTypes) || suggestionTypes.Contains("people"))
                        {
                            List<int> suggestionsPeople = _keui.SuggestPeopleForPrefix(prefix);
                            foreach (var personId in suggestionsPeople)
                            {
                                var personInfo = _keui.PeopleData.GetPerson(personId);
                                var accountIds = personInfo.GetAccountIds().ToList();
                                string account = "";
                                if (accountIds.Count > 0)
                                    account = _keui.PeopleData.GetAccount(accountIds[0]);
                                string name = _keui.GetSuggestedPersonName(personInfo.PersonId);
                                keuiResponseData += String.Format("<person name=\"{0}\" account=\"{1}\" uuid=\"{2}\" />", name.EncodeXMLString(), account.EncodeXMLString(), personInfo.CustomData.EncodeXMLString());
                            }
                        }
                        if (string.IsNullOrEmpty(suggestionTypes) || suggestionTypes.Contains("products")) {
                            foreach (var sugg in _keui.SuggestProductsForPrefix(prefix))
                                keuiResponseData += String.Format("<product label=\"{0}\" uri=\"{1}\" />", sugg.Item1.EncodeXMLString(), sugg.Item2.EncodeXMLString());
                        }
                        if (string.IsNullOrEmpty(suggestionTypes) || suggestionTypes.Contains("issues")) {
                            foreach (var sugg in _keui.SuggestIssuesForPrefix(prefix))
                                keuiResponseData += String.Format("<issue label=\"{0}\" uri=\"{1}\" />", sugg.Item1.EncodeXMLString(), sugg.Item2.EncodeXMLString());
                        }
                        if (string.IsNullOrEmpty(suggestionTypes) || suggestionTypes.Contains("sources"))
                        {
                            foreach (int fileTag in _keui.SuggestFilesForPrefix(prefix)) {
                                string fileName = _keui.MailData.GetTagName(fileTag);
                                string fileUri = _keui.MailData.GetTagIdStr(fileTag);
                                fileUri = _keui.MakeUriLong(fileUri);
                                keuiResponseData += String.Format("<file name=\"{0}\" uri=\"{1}\" tooltip=\"{2}\" />", fileName.EncodeXMLString(), fileUri.EncodeXMLString(), fileName.EncodeXMLString());
                            }
                            foreach (int moduleTag in _keui.SuggestModulesForPrefix(prefix)) {
                                int fileTag = _keui.MailData.GetParentTagId(moduleTag);
                                string fileName = fileTag != TagInfoBase.InvalidTagId ? _keui.MailData.GetTagName(fileTag) : "";
                                string moduleUri = _keui.MailData.GetTagIdStr(moduleTag);
                                moduleUri = _keui.MakeUriLong(moduleUri);
                                keuiResponseData += String.Format("<module name=\"{0}\" uri=\"{1}\" tooltip=\"{2}\" />", _keui.MailData.GetTagName(moduleTag).EncodeXMLString(), moduleUri.EncodeXMLString(), fileName.EncodeXMLString());
                            }
                            foreach (int methodTag in _keui.SuggestMethodsForPrefix(prefix)) {
                                int moduleTag = _keui.MailData.GetParentTagId(methodTag);
                                int fileTag = moduleTag != TagInfoBase.InvalidTagId ? _keui.MailData.GetParentTagId(moduleTag) : TagInfoBase.InvalidTagId;
                                string fileName = fileTag != TagInfoBase.InvalidTagId ? _keui.MailData.GetTagName(fileTag) : "";
                                string methodUri = _keui.MailData.GetTagIdStr(methodTag);
                                methodUri = _keui.MakeUriLong(methodUri);
                                keuiResponseData += String.Format("<method name=\"{0}\" uri=\"{1}\" tooltip=\"{2}\" />", _keui.MailData.GetTagName(methodTag).EncodeXMLString(), methodUri.EncodeXMLString(), fileName.EncodeXMLString());
                            }
                        }
                        keuiResponseData += "</suggestions>";
                    }
                    else if (requestType == "GetAnnotationOntologyRDF")
                    {
                        var queryNode = requestNode.SelectSingleNode("./s1:requestData/query");
                        bool includeComment = queryNode != null && (queryNode.GetAttributeValue("includeComment", 0) == 1);
                        bool includeLinksTo = queryNode != null && (queryNode.GetAttributeValue("includeLinksTo", 0) == 1);
                        keuiResponseData = _keui.GetAnnotationOntologyRDF(includeComment, includeLinksTo);
                        AddEvent("Returning Annotation Ontology RDF. Data contains " + (int)(keuiResponseData.Length / 1024) + "KB");
                    }
                    else
                        keuiResponseData = _keui.ProcessKEUIRequest(xmlDoc, requestType);

                    if (keuiResponseData == null) return;

                    // update the event name
                    UpdateEventMetaData(xmlDoc, _activeMQSettings.TopicNameKEUIPublishResponse);

                    // insert the return data
                    _keui.AddNewLines(eventDataNode, 8);
                    eventDataNode.AppendChild(xmlDoc.CreateTextNode(String.Format("<s1:keuiResponse>{0}</s1:keuiResponse>", keuiResponseData)));

                    string returnEvent = xmlDoc.DocumentNode.OuterHtml;

                    // publish it
                    StoreEventData(publishTopic, returnEvent);
                    using (var publisher = new ActiveMqHelper.TopicPublisher(AQSession, publishTopic))
                    {
                        publisher.SendMessage(returnEvent);
                    }
                    AddEvent("KEUI successfully published KEUI Response event on topic " + publishTopic);
                }
            }
            //catch (Apache.NMS.ActiveMQ.IOException ioe)
            //{
            //    DisposeActiveMQ();
            //    InitActiveMQ();
            //}
            catch (Exception ex)
            {
                AddEvent("Exception while processing KEUI request: " + ex.Message);
                GenLib.Log.LogService.LogException("Exception while processing KEUI request. message: " + message, ex);
            }
        }
        private string AddItemContent(QueryBase query, string returnData)
        {
            if (string.IsNullOrEmpty(returnData))
                return returnData;

            bool addItemData = false;
            int itemDataSnipLen = -1;
            bool snipMatchKeywords = true;
            int keywordMatchOffset = 25;
            List<string> keywords = new List<string>();

            if (query is GeneralQuery) {
                GeneralQuery generalQuery = query as GeneralQuery;
                addItemData = generalQuery.QueryParams.ResultData.HasFlag(QResultData.itemData);
                itemDataSnipLen = generalQuery.QueryParams.ItemDataSnipLen;
                snipMatchKeywords = generalQuery.QueryParams.SnipMatchKeywords;
                keywordMatchOffset = generalQuery.QueryParams.KeywordMatchOffset;
                foreach (QKeywordCond kwCond in from arg in generalQuery.QueryArgs.Conditions where arg is QKeywordCond select arg)
                    keywords.AddRange(from kw in kwCond.Keywords select kw.Keyword);
            }
            else if (query is CustomQuery) {
                CustomQuery customQuery = query as CustomQuery;
                if (customQuery.QueryParams is QSimilarThreadsParam) {
                    addItemData = (customQuery.QueryParams as QSimilarThreadsParam).IncludeItemData;
                    itemDataSnipLen = (customQuery.QueryParams as QSimilarThreadsParam).ItemDataSnipLen;
                }
                else if (customQuery.QueryParams is QSimilarItemsParam) {
                    addItemData = (customQuery.QueryParams as QSimilarItemsParam).IncludeItemData;
                    itemDataSnipLen = (customQuery.QueryParams as QSimilarItemsParam).ItemDataSnipLen;
                }
                foreach (QKeywordCond kwCond in from arg in customQuery.QueryArgs.Conditions where arg is QKeywordCond select arg)
                    keywords.AddRange(from kw in kwCond.Keywords select kw.Keyword);
            }

            if (!addItemData)
                return returnData;

            HtmlAgilityPack.XmlDocument returnDoc = new HtmlAgilityPack.XmlDocument();
            returnDoc.LoadXml(returnData);

            foreach (HtmlAgilityPack.HtmlNode itemNode in returnDoc.DocumentNode.SelectNodes("//item") ?? new HtmlNodeCollection(null)) {
                try {
                    int itemId = itemNode.GetAttributeValue("id", -1);
                    if (itemId == -1)
                        continue;
                    Tuple<string, string, string> subjectBodyMeta = SQLGetItemSubjectBodyMeta(itemId);
                    string subject = subjectBodyMeta.Item1;
                    string body = subjectBodyMeta.Item2;
                    string meta = subjectBodyMeta.Item3;

                    int firstIndex = -1;
                    string title;

                    if (itemDataSnipLen != -1) {
                        for (int i = 0; i < keywords.Count && i < 10; i++) {
                            int index = body.IndexOf(keywords[i], StringComparison.InvariantCultureIgnoreCase);
                            if (index >= 0 && (firstIndex == -1 || index < firstIndex))
                                firstIndex = index;
                        }
                        if (firstIndex > 0)
                            firstIndex -= keywordMatchOffset;
                        while (firstIndex > 0 && !char.IsWhiteSpace(body[firstIndex]))
                            firstIndex--;
                        if (firstIndex + itemDataSnipLen > body.Length)
                            firstIndex = body.Length - itemDataSnipLen;
                        firstIndex = Math.Max(0, firstIndex);
                        body = body.Substring(firstIndex, Math.Min(itemDataSnipLen, body.Length - firstIndex));
                        title = "shortContent";
                    }
                    else
                        title = "fullContent";
                    HtmlNode bodyNode = returnDoc.CreateElement(title);
                    bodyNode.AppendChild(returnDoc.CreateTextNode(body.EncodeXMLString()));
                    itemNode.AppendChild(bodyNode);

                    HtmlNode subjectNode = returnDoc.CreateElement("subject");
                    subjectNode.AppendChild(returnDoc.CreateTextNode(subject.EncodeXMLString()));
                    itemNode.AppendChild(subjectNode);

                    HtmlNode metaNode = returnDoc.CreateElement("metaData");
                    metaNode.AppendChild(returnDoc.CreateTextNode(meta));
                    itemNode.AppendChild(metaNode);
                }
                catch (Exception ex) {
                    GenLib.Log.LogService.LogException("MailData. AddItemContent: ", ex);
                }
            }

            returnData = returnDoc.DocumentNode.InnerHtml;
            return returnData;
        }