public void RegardingObjectSearchCommand(string term, Action <EntityCollection> callback)
        {
            string regardingAccountFetchXml     = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
                                  <entity name='account'>
                                    <attribute name='name' />
                                    <attribute name='accountid' />
                                    <order attribute='name' descending='false' />
                                    <filter type='and'>
                                      <condition attribute='statecode' operator='eq' value='0' />
                                      <condition attribute='name' operator='like' value='%{0}%' />
                                      {1}
                                    </filter>
                                   </entity>
                                </fetch>";
            string regardingOpportunityFetchXml = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
                                                  <entity name='opportunity'>
                                                    <attribute name='name' />
                                                    <attribute name='opportunityid' />
                                                    <order attribute='name' descending='false' />
                                                    <filter type='and'>
                                                      <condition attribute='statecode' operator='eq' value='0' />
                                                      <condition attribute='name' operator='like' value='%{0}%' />
                                                     {1}
                                                    </filter>
                                                  </entity>
                                                </fetch>";

            string regardingIncidentFetchXml = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
                                              <entity name='incident'>
                                                <attribute name='title' />
                                                <attribute name='incidentid' />
                                                <order attribute='title' descending='false' />
                                                <filter type='and'>
                                                  <condition attribute='title' operator='like' value='%{0}%' />
                                                  {1}
                                                </filter>
                                              </entity>
                                            </fetch>";

            string   accountCriteriaFetchXml = @"<condition attribute='{0}' operator='eq' value='{1}' />";
            DayEntry selectedItem            = this.Days.SelectedItems[0];


            List <Entity> unionedResults = new List <Entity>();

            // We need to union the activities regarding the account directly with those that are regarding related records
            Action <string, string, string, Action, Action> unionSearch = delegate(string fetchXml, string nameAttribute, string accountAttribute, Action completeCallBack, Action errorCallBack)
            {
                // Add Account filter if an account is selected
                string additionalCriteria = "";
                if (selectedItem != null && selectedItem.Account != null)
                {
                    additionalCriteria = string.Format(accountCriteriaFetchXml, accountAttribute, selectedItem.Account.Id.Value);
                }
                string queryFetchXml = string.Format(fetchXml, XmlHelper.Encode(term), additionalCriteria);
                OrganizationServiceProxy.BeginRetrieveMultiple(queryFetchXml, delegate(object result)
                {
                    EntityCollection fetchResult = OrganizationServiceProxy.EndRetrieveMultiple(result, typeof(ActivityPointer));
                    // Adjust the entity types
                    foreach (Entity a in fetchResult.Entities)
                    {
                        // Set name
                        a.SetAttributeValue("displayName", a.GetAttributeValueString(nameAttribute));
                        unionedResults.Add(a);
                    }

                    completeCallBack();
                });
            };

            TaskIterrator tasks = new TaskIterrator();

            // Add Searches
            tasks.AddTask(delegate(Action completeCallBack, Action errorCallBack) { unionSearch(regardingAccountFetchXml, "name", "accountid", completeCallBack, errorCallBack); });
            tasks.AddTask(delegate(Action completeCallBack, Action errorCallBack) { unionSearch(regardingOpportunityFetchXml, "name", "customerid", completeCallBack, errorCallBack); });
            tasks.AddTask(delegate(Action completeCallBack, Action errorCallBack) { unionSearch(regardingIncidentFetchXml, "title", "customerid", completeCallBack, errorCallBack); });

            Action queryComplete = delegate()
            {
                //  Sort Alphabetically
                unionedResults.Sort(delegate(Entity a, Entity b) { return(Entity.SortDelegate("displayName", a, b)); });
                // Completed the queryies, so sort then and add to Entity Collection
                EntityCollection results = new EntityCollection(unionedResults);

                callback(results);
            };

            // Start processing queue
            tasks.Start(queryComplete, null);
        }
        public void ActivitySearchCommand(string term, Action <EntityCollection> callback)
        {
            // Get the option set values

            string fetchXml = @"<fetch version='1.0' output-format='xml-platform' mapping='logical' distinct='false'>
                                  <entity name='activitypointer'>
                                    <attribute name='activitytypecode' />
                                    <attribute name='subject' />
                                    <attribute name='activityid' />
                                    <attribute name='instancetypecode' />
                                    <attribute name='regardingobjectid' />
                                    <order attribute='modifiedon' descending='false' />
                                    <filter type='and'>
                                      <condition attribute='ownerid' operator='eq-userid' />
                                        <condition attribute='subject' operator='like' value='%{0}%' />
                                          <condition attribute='activitytypecode' operator='in'>
                                            <value>4202</value>
                                            <value>4207</value>
                                            <value>4210</value>
                                            <value>4212</value>
                                          </condition>
                                            {2}
                                    </filter>
                                    {1}
                                  </entity>
                                </fetch>";
            // Get the account to filter on if there is one
            string regardingObjectIdFilterFetchXml = @"<condition attribute='regardingobjectid' operator='eq' value='{0}'/>";

            string opportunityAccountFilterFetchXml = @"<link-entity name='opportunity' from='opportunityid' to='regardingobjectid' visible='false' link-type='inner' alias='opportunity' >
                                        <attribute name='customerid' />
                                        <filter type='and' >
                                            <condition attribute='customerid' operator='eq' value='{0}' />
                                        </filter>
                                        </link-entity>";

            string incidentAccountFilterFetchXml = @" <link-entity name='incident' from='incidentid' to='regardingobjectid' visible='false' link-type='inner' alias='incident' >
                                        <attribute name='customerid' />
                                        <filter type='and' >
                                            <condition attribute='customerid' operator='eq' value='{0}' />
                                        </filter>
                                        </link-entity>";

            string contractAccountFilterFetchXml = @" <link-entity name='contract' from='contractid' to='regardingobjectid' visible='false' link-type='inner' alias='contract' >
                                        <attribute name='customerid' />
                                        <filter type='and' >
                                            <condition attribute='customerid' operator='eq' value='{0}' />
                                        </filter>
                                        </link-entity>";

            string regardingAccountFilterFetchXml = @" <link-entity name='account' from='accountid' to='regardingobjectid' visible='false' link-type='inner' alias='account' >
                                        <attribute name='accountid'/>
                                        <attribute name='name'/>
                                        <filter type='and' >
                                            <condition attribute='accountid' operator='eq' value='{0}' />
                                        </filter>
                                        </link-entity>";

            DayEntry selectedItem             = this.Days.SelectedItems[0];
            string   regardingObjectFilter    = String.Empty;
            string   regardingAccountFilter   = String.Empty;
            string   opportunityAccountFilter = String.Empty;
            string   incidentAccountFilter    = String.Empty;
            string   contractAccountFilter    = String.Empty;

            if (selectedItem != null && selectedItem.RegardingObjectId != null)
            {
                regardingObjectFilter = string.Format(regardingObjectIdFilterFetchXml, selectedItem.RegardingObjectId.Id.Value);
            }

            if (selectedItem != null && selectedItem.Account != null)
            {
                // Add in the regarding account filter
                regardingAccountFilter   = string.Format(regardingAccountFilterFetchXml, selectedItem.Account.Id.Value);
                opportunityAccountFilter = string.Format(opportunityAccountFilterFetchXml, selectedItem.Account.Id.Value);
                incidentAccountFilter    = string.Format(incidentAccountFilterFetchXml, selectedItem.Account.Id.Value);
                contractAccountFilter    = string.Format(contractAccountFilterFetchXml, selectedItem.Account.Id.Value);
            }

            List <Entity> unionedResults = new List <Entity>();

            // We need to union the activities regarding the account directly with those that are regarding related records
            Action <string, string, Action, Action> unionSearch = delegate(string additionalFilter, string additionalCriteria, Action completeCallBack, Action errorCallBack)
            {
                string queryFetchXml = string.Format(fetchXml, XmlHelper.Encode(term), additionalFilter, additionalCriteria);
                OrganizationServiceProxy.BeginRetrieveMultiple(queryFetchXml, delegate(object result)
                {
                    EntityCollection fetchResult = OrganizationServiceProxy.EndRetrieveMultiple(result, typeof(ActivityPointer));
                    // Adjust the entity types
                    foreach (ActivityPointer a in fetchResult.Entities)
                    {
                        a.UpdateCalculatedFields();
                        unionedResults.Add(a);
                    }

                    completeCallBack();
                });
            };

            TaskIterrator tasks = new TaskIterrator();

            // Default Search
            tasks.AddTask(delegate(Action completeCallBack, Action errorCallBack) { unionSearch(regardingAccountFilter, regardingObjectFilter, completeCallBack, errorCallBack); });

            // Associated record searches
            if (opportunityAccountFilter != String.Empty)
            {
                tasks.AddTask(delegate(Action completeCallBack, Action errorCallBack) { unionSearch(opportunityAccountFilter, String.Empty, completeCallBack, errorCallBack); });
            }
            if (incidentAccountFilter != String.Empty)
            {
                tasks.AddTask(delegate(Action completeCallBack, Action errorCallBack) { unionSearch(incidentAccountFilter, String.Empty, completeCallBack, errorCallBack); });
            }
            if (contractAccountFilter != String.Empty)
            {
                tasks.AddTask(delegate(Action completeCallBack, Action errorCallBack) { unionSearch(contractAccountFilter, String.Empty, completeCallBack, errorCallBack); });
            }


            Action queryComplete = delegate()
            {
                // Sort
                unionedResults.Sort(delegate(Entity a, Entity b) { return(Entity.SortDelegate("subject", a, b)); });
                // Completed the queryies, so sort then and add to Entity Collection
                EntityCollection results = new EntityCollection(unionedResults);

                callback(results);
            };

            // Start processing queue
            tasks.Start(queryComplete, null);
        }