/*  This method calls
         *  WC_Contacts_BSClient : WC_Contacts_BSQueryPage
         *  Called by SRlistVirtualTable GetRows() to display Service Requests for a contact
         */
        public ServiceRequest[] LookupSRbyContactPartyID(IList<string> columns, string contact_id, int _logIncidentId = 0, int _logContactId = 0)
        {
            if (String.IsNullOrWhiteSpace(SRURL) || String.IsNullOrWhiteSpace(SRServiceUsername) || String.IsNullOrWhiteSpace(SRServicePassword))
            {
                throw new Exception("Provider's InitForSR is not run.");
            }
            string request, response, logMessage, logNote;
            binding.MaxReceivedMessageSize = 2147483647;
            CONTACTSVC.WC_Contacts_BSClient client = new CONTACTSVC.WC_Contacts_BSClient(binding, addr);
            MyEndpointBehavior eBehavior = new MyEndpointBehavior();
            client.Endpoint.Behaviors.Add(eBehavior);
            if(SRServiceTimeout > 0)
                client.InnerChannel.OperationTimeout = TimeSpan.FromMilliseconds(SRServiceTimeout );
            CONTACTSVC.WC_Contacts_BSQueryPage_Input ip = new CONTACTSVC.WC_Contacts_BSQueryPage_Input();

            ip.ListOfWc_Contacts_Io = new CONTACTSVC.ListOfWc_Contacts_IoQuery();
            ip.ListOfWc_Contacts_Io.Contact = new CONTACTSVC.ContactQuery();

            ip.ListOfWc_Contacts_Io.Contact.Id = new CONTACTSVC.queryType();
            ip.ListOfWc_Contacts_Io.Contact.Id.Value = "='" + contact_id + "'";

            ip.ListOfWc_Contacts_Io.Contact.ListOfServiceRequest = new CONTACTSVC.ListOfServiceRequestQuery();
            ip.ListOfWc_Contacts_Io.Contact.ListOfServiceRequest.ServiceRequest = new CONTACTSVC.ServiceRequestQuery();
            ip.ListOfWc_Contacts_Io.Contact.ListOfServiceRequest.ServiceRequest.SRNumber = new CONTACTSVC.queryType();
           
            foreach (PropertyInfo propertyInfo in ip.ListOfWc_Contacts_Io.Contact.ListOfServiceRequest.ServiceRequest.GetType().GetProperties())
            {
                /* bc Incident/SR report tab is a special case, the columns are hard coded and fixed
                 * to show the combined rnow and siebel rows, IntegratrionId, summary, Id
                 * are diffent name
                 */
                foreach (string column in columns)
                {
                    if (propertyInfo.Name == column.Split('.')[1] ||
                        propertyInfo.Name == "IntegrationId" ||
                        propertyInfo.Name == "Id" ||
                        propertyInfo.Name == "Abstract"
                       )
                    {
                        if (propertyInfo.PropertyType == typeof(CONTACTSVC.queryType))
                        {
                            CONTACTSVC.queryType queryType = new CONTACTSVC.queryType();
                            propertyInfo.SetValue(ip.ListOfWc_Contacts_Io.Contact.ListOfServiceRequest.ServiceRequest, queryType, null);
                        }
                        break;
                    }
                }
            }

            ip.LOVLanguageMode = "LIC";
            ip.ViewMode = "All";

            Stopwatch stopwatch = new Stopwatch();
            CONTACTSVC.WC_Contacts_BSQueryPage_Output opList;
            try
            {
                using (new OperationContextScope(client.InnerChannel))
                {
                    MessageHeader usrMsgHdr = MessageHeader.CreateHeader("UsernameToken", "http://siebel.com/webservices", SRServiceUsername);
                    OperationContext.Current.OutgoingMessageHeaders.Add(usrMsgHdr);
                    MessageHeader pwdMsgHdr = MessageHeader.CreateHeader("PasswordText", "http://siebel.com/webservices", SRServicePassword);
                    OperationContext.Current.OutgoingMessageHeaders.Add(pwdMsgHdr);
                    stopwatch.Start();
                    opList = client.WC_Contacts_BSQueryPage(ip);
                    stopwatch.Stop();
                    request = eBehavior.msgInspector.reqPayload;
                    logMessage = "Request of SRs by contactID (Success). Siebel Contact ID = " + contact_id;
                    logNote = "Request Payload: " + request;
                    log.DebugLog(_logIncidentId, _logContactId, logMessage, logNote);
                    response = eBehavior.msgInspector.resPayload;
                    logMessage = "Response of SRs by contactID (Success). Siebel Contact ID = " + contact_id;
                    logNote = "Response Payload: " + response;
                    log.DebugLog(_logIncidentId, _logContactId, logMessage, logNote, (int)stopwatch.ElapsedMilliseconds);
                }
            }
            catch (Exception ex)
            {
                request = eBehavior.msgInspector.reqPayload;
                logMessage = "Request of SRs by contactID (Failure). Siebel Contact ID = " + contact_id;
                logNote = "Request Payload: " + request;
                log.DebugLog(_logIncidentId, _logContactId, logMessage, logNote);
                response = eBehavior.msgInspector.resPayload;
                logMessage = "Response of SRs by contactID (Failure). Siebel Contact ID = " + contact_id;
                logNote = "Response Payload: " + response;
                log.DebugLog(_logIncidentId, _logContactId, logMessage, logNote);
                handleSiebelException(ex, "LookupSRbyContactPartyID");
                throw ex;
            }

            CONTACTSVC.ContactData contactData = opList.ListOfWc_Contacts_Io.Contact[0];
            if (contactData.ListOfServiceRequest.ServiceRequest == null)
                return null;

            ServiceRequest[] retvals = new ServiceRequest[contactData.ListOfServiceRequest.ServiceRequest.Length];
            int i = 0;
            foreach (CONTACTSVC.ServiceRequestData sr in contactData.ListOfServiceRequest.ServiceRequest)
            {
                if (sr.IntegrationId == null || sr.IntegrationId == "")
                {
                    ServiceRequest req = new ServiceRequest();
                    req.RequestID = sr.Id;
                    req.RequestNumber = sr.SRNumber;
                    req.Status = sr.Status;
                    req.Summary = sr.Abstract;
                    req.RequestDate = (DateTime)sr.Created;
                    retvals[i] = req;
                    i++;
                }
            }

            return retvals;
        }
        /* This method calls
         * WC_Contacts_BSClient.WC_Contacts_BSQueryPage(ip)
         * Its output is a table, foreach loop is used 
         * (even though only one row is returned by setting record limit = 1)
         * ContactData is generated and need to be updated 
         * if proxy is regenerated
         *  call dictAddProperty() to add the individual property name, type, and value
         *  for dynamic columns feature
         */
        public Dictionary<string, string> LookupContactDetail(IList<string> columns, string party_id, int _logIncidentId = 0, int _logContactId = 0)
        {
            // can reuse SRURL, service username and password, is all the same 
            if (String.IsNullOrWhiteSpace(ContactURL) || String.IsNullOrWhiteSpace(ContactServiceUsername) || String.IsNullOrWhiteSpace(ContactServicePassword))
            {
                throw new Exception("Provider's InitForContact not run.");
            }
            string request, response, logMessage, logNote;
            CONTACTSVC.WC_Contacts_BSClient client = new CONTACTSVC.WC_Contacts_BSClient(binding, addr);
            CONTACTSVC.WC_Contacts_BSQueryPage_Input ip = new CONTACTSVC.WC_Contacts_BSQueryPage_Input();
            MyEndpointBehavior eBehavior = new MyEndpointBehavior();
            client.Endpoint.Behaviors.Add(eBehavior);
            if(ContactServiceTimeout > 0)
                client.InnerChannel.OperationTimeout = TimeSpan.FromMilliseconds(ContactServiceTimeout);

            ip.ListOfWc_Contacts_Io = new CONTACTSVC.ListOfWc_Contacts_IoQuery();
            ip.ListOfWc_Contacts_Io.Contact = new CONTACTSVC.ContactQuery();

            foreach (PropertyInfo propertyInfo in ip.ListOfWc_Contacts_Io.Contact.GetType().GetProperties())
            {
                foreach (string column in columns)
                {
                    if (propertyInfo.Name == column.Split('.')[1])
                    {
                        if (propertyInfo.PropertyType == typeof(CONTACTSVC.queryType))
                        {
                            CONTACTSVC.queryType queryType = new CONTACTSVC.queryType();
                            propertyInfo.SetValue(ip.ListOfWc_Contacts_Io.Contact, queryType, null);
                        }
                        break;
                    }
                }
            }

            if (ip.ListOfWc_Contacts_Io.Contact.Id == null)
                ip.ListOfWc_Contacts_Io.Contact.Id = new CONTACTSVC.queryType();

            ip.ListOfWc_Contacts_Io.Contact.Id.Value = "='" + party_id + "'";

            ip.LOVLanguageMode = "LIC";
            ip.ViewMode = "All";

            CONTACTSVC.WC_Contacts_BSQueryPage_Output opList;
            Stopwatch stopwatch = new Stopwatch();
            try
            {
                using (new OperationContextScope(client.InnerChannel))
                {
                    MessageHeader usrMsgHdr = MessageHeader.CreateHeader("UsernameToken", "http://siebel.com/webservices", ContactServiceUsername);
                    OperationContext.Current.OutgoingMessageHeaders.Add(usrMsgHdr);
                    MessageHeader pwdMsgHdr = MessageHeader.CreateHeader("PasswordText", "http://siebel.com/webservices", ContactServicePassword);
                    OperationContext.Current.OutgoingMessageHeaders.Add(pwdMsgHdr);
                    stopwatch.Start();
                    opList = client.WC_Contacts_BSQueryPage(ip);
                    stopwatch.Stop();
                    request = eBehavior.msgInspector.reqPayload;
                    logMessage = "Request of contact detail (Success). Siebel Contact ID = " + party_id;
                    logNote = "Request Payload: " + request;
                    log.DebugLog(_logIncidentId, _logContactId, logMessage, logNote);
                    response = eBehavior.msgInspector.resPayload;
                    logMessage = "Response of contact detail (Success). Siebel Contact ID = " + party_id;
                    logNote = "Response Payload: " + response;
                    log.DebugLog(_logIncidentId, _logContactId, logMessage, logNote);
                }
            }
            catch (Exception ex)
            {
                request = eBehavior.msgInspector.reqPayload;
                logMessage = "Request of contact detail (Failure). Siebel Contact ID = " + party_id;
                logNote = "Request Payload: " + request;
                log.DebugLog(_logIncidentId, _logContactId, logMessage, logNote);
                response = eBehavior.msgInspector.resPayload;
                logMessage = "Response of contact detail (Failure). Siebel Contact ID = " + party_id;
                logNote = "Response Payload: " + response;
                log.DebugLog(_logIncidentId, _logContactId, logMessage, logNote, (int)stopwatch.ElapsedMilliseconds);
                handleSiebelException(ex, "client.WC_Contacts_BSQueryPage(ip)");
                throw ex;
            }
            Dictionary<string, string> dictDetail = new Dictionary<string, string>();

            CONTACTSVC.ContactData contactData = opList.ListOfWc_Contacts_Io.Contact[0];
            foreach (PropertyInfo propertyInfo in contactData.GetType().GetProperties())
            {
                Object propVal = contactData.GetType().GetProperty(propertyInfo.Name).GetValue(contactData, null);
                dictAddProperty(propertyInfo, propVal, ref dictDetail);
            }

            return dictDetail;
        }