/// <summary>
        /// This method does Contact Search and return results. 
        /// </summary>
        /// <param name="searchCriteria">Search Criteria</param>
        /// <returns>List of Contacts</returns>
        public async Task<List<Contact>> SearchContacts(string searchCriteria)
        {
            // Get AccessToken
            _proxy.AccessToken = await ADALHelper.GetTokenSilent();

            var searchResults = new List<Contact>();

            string fetch = String.Format(@"<fetch version='1.0' output-format='xml-platform' top='50' mapping='logical' distinct='false'>
  <entity name='contact'>
    <attribute name='fullname' />
    <attribute name='jobtitle' />
    <order attribute='fullname' descending='false' />
    <filter type='and'>
      <condition attribute='fullname' operator='like' value='%{0}%' />
    </filter>
    <link-entity name='account' from='accountid' to='parentcustomerid' visible='false' link-type='outer' alias='ab'>
      <attribute name='name' />
    </link-entity>
  </entity>
</fetch>", searchCriteria);
                        
            EntityCollection results = await _proxy.RetrieveMultiple(new FetchExpression(fetch));

            // If there is results then process it.
            if (results.Entities.Count > 0)
            {
                foreach (Entity result in results.Entities)
                {
                    // Instantiate Contact and fullfill partially
                    Contact contact = new Contact()
                    {
                        Id = result.Id,
                        FullName = result["fullname"].ToString(),
                        // Combine Company Name and JobTitle
                        ParentCompany = (result["ab.name"] != null) ? (result["ab.name"] as AliasedValue).Value.ToString() : "",
                        JobTitle = (result.Contains("jobtitle")) ? result["jobtitle"].ToString() : ""
                    };
                    searchResults.Add(contact);
                }
            }

            return searchResults;
        }
        /// <summary>
        /// This method maintain Recently Used Contacts
        /// </summary>
        /// <param name="contact">Contact record</param>
        public void UpdateRecentContacts(Contact contact)
        {
            var recentContact = _settings.RecentContacts;

            // Update Recently Used Contacts
            if (recentContact.Where(x => x.Id == contact.Id).FirstOrDefault() != null)
            {
                // If the record is already on top of the list, then do nothing.
                if (recentContact.IndexOf(recentContact.Where(x => x.Id == contact.Id).First()) == 0)
                    return;

                // otherwise remove from the list first.
                recentContact.Remove(recentContact.Where(x => x.Id == contact.Id).First());
            }

            // If Recently Used Contacts is already 10, then removed the oldest one.
            if (recentContact.Count == 10)
                recentContact.RemoveAt(9);

            // Add currently selected record on top of the list.
            recentContact.Insert(0, contact);

            _settings.RecentContacts = recentContact;
        }
        /// <summary>
        /// This method firstly create task, then complete it if passed task does not have id.
        /// If passed entity has id, then change state back to active first, update data, then 
        /// complete it again.
        /// </summary>
        /// <param name="activity">Activity Record to update</param>
        /// <param name="contact">Contact Record for regarding information</param>
        public async Task UpsertTask(Activity activity, Contact contact)
        {
            // Get AccessToken
            _proxy.AccessToken = await ADALHelper.GetTokenSilent();

            // Instantiate a Task entity.
            Entity task = new Entity("task");
            task["subject"] = activity.Subject;
            task["actualstart"] = activity.ActualEnd.Date;
            task["actualend"] = activity.ActualEnd.Date;
            task["description"] = activity.Notes;
            task["regardingobjectid"] = new EntityReference("contact", contact.Id);
            task.Id = activity.Id;

            // If passed data does not have id, then its new operation.
            if (task.Id == null || task.Id == Guid.Empty)
            {
                // Create record first
                Guid taskId = await _proxy.Create(task);


                // Then complete it
                SetStateRequest setStateRequest = new SetStateRequest()
                {
                    EntityMoniker = new EntityReference("task", taskId),
                    State = new OptionSetValue(1),
                    Status = new OptionSetValue(5)
                };
                await _proxy.Execute(setStateRequest);
            }
            else
            {
                // First set state back to active
                SetStateRequest setStateRequest = new SetStateRequest()
                {
                    EntityMoniker = new EntityReference("task", task.Id),
                    State = new OptionSetValue(0),
                    Status = new OptionSetValue(3)
                };
                await _proxy.Execute(setStateRequest);

                // then update task
                await _proxy.Update(task);

                // finally complete it again
                setStateRequest = new SetStateRequest()
                {
                    EntityMoniker = new EntityReference("task", task.Id),
                    State = new OptionSetValue(1),
                    Status = new OptionSetValue(5)
                };
                await _proxy.Execute(setStateRequest);
            }
        }
        /// <summary>
        /// This method retrives a contact as late bound. 
        /// </summary>
        /// <param name="id">Contact Id</param>
        /// <returns>Contact Record</returns>
        public async Task<Contact> RetrieveContact(Guid id)
        {
            // Get AccessToken
            _proxy.AccessToken = await ADALHelper.GetTokenSilent();

            Entity result = await _proxy.Retrieve("contact", id, new ColumnSet("fullname", "address1_composite", "jobtitle", "parentcustomerid", "emailaddress1", "telephone1", "entityimage"));

            Contact contact = new Contact()
            {
                Id = result.Id,
                FullName = result["fullname"].ToString(),
                Address1 = (result.Contains("address1_composite")) ? result["address1_composite"].ToString() : "",
                JobTitle = (result.Contains("jobtitle")) ? result["jobtitle"].ToString() : "",               
                ParentCompany = (result["parentcustomerid"] == null) ? null : (result["parentcustomerid"] as EntityReference).Name.ToString(),
                Email1 = (result.Contains("emailaddress1")) ? result["emailaddress1"].ToString() : "",
                Telephone1 = (result.Contains("telephone1")) ? result["telephone1"].ToString() : "",
                EntityImage = result["entityimage"] as byte[]
            };

            // Return the result
            return contact;
        }        
        /// <summary>
        /// This method does Contact Search and return results. 
        /// </summary>
        /// <param name="searchCriteria">Search Criteria</param>
        /// <returns>List of Contacts</returns>
        public async Task<List<Contact>> SearchContacts(string searchCriteria)
        {
            // Get AccessToken
            _proxy.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await ADALHelper.GetTokenSilent());

            var searchResults = new List<Contact>();

            string fetch = String.Format(@"<fetch version='1.0' output-format='xml-platform' top='50' mapping='logical' distinct='false'>
  <entity name='contact'>
    <attribute name='fullname' />
    <attribute name='jobtitle' />
    <order attribute='fullname' descending='false' />
    <filter type='and'>
      <condition attribute='fullname' operator='like' value='%{0}%' />
    </filter>
    <link-entity name='account' from='accountid' to='parentcustomerid' visible='false' link-type='outer' alias='ab'>
      <attribute name='name' />
    </link-entity>
  </entity>
</fetch>", searchCriteria);

            // Use FetchXML to get data
            HttpResponseMessage retrieveRes = await _proxy.GetAsync(string.Format("contacts?fetchXml={0}", System.Uri.EscapeDataString(fetch)));
            JToken results = JObject.Parse(retrieveRes.Content.ReadAsStringAsync().Result)["value"];
            
            foreach (JToken result in results)
            {
                // Instantiate Contact and fullfill partially
                Contact contact = new Contact()
                {
                    Id = (Guid)result["contactid"],
                    FullName = result["fullname"].ToString(),
                    // Combine Company Name and JobTitle
                    ParentCompany = (result["ab_x002e_name"] != null) ? result["ab_x002e_name"].ToString() : "",
                    JobTitle = (result["jobtitle"] != null) ? result["jobtitle"].ToString() : ""
                };
                searchResults.Add(contact);
            }

            return searchResults;
        }
        /// <summary>
        /// This method firstly create task, then complete it if passed task does not have id.
        /// If passed entity has id, then change state back to active first, update data, then 
        /// complete it again.
        /// </summary>
        /// <param name="activity">Activity Record to update</param>
        /// <param name="contact">Contact Record for regarding information</param>
        public async Task UpsertTask(Activity activity, Contact contact)
        {
            // Get AccessToken
            _proxy.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await ADALHelper.GetTokenSilent());
            
            // If passed data does not have id, then its new operation.
            if (activity.Id == null || activity.Id == Guid.Empty)
            {                
                // Create task object
                JObject task = new JObject();
                task["subject"] = activity.Subject;

                task["actualstart"] = activity.ActualEnd;
                task["actualend"] = activity.ActualEnd;
                task["description"] = activity.Notes;
                task["*****@*****.**"] = "/contacts(" + contact.Id + ")";
                
                // Create record first
                HttpRequestMessage createReq = new HttpRequestMessage(HttpMethod.Post, "tasks");
                createReq.Content = new StringContent(JsonConvert.SerializeObject(
                    task, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore }));

                createReq.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

                HttpResponseMessage result = await _proxy.SendAsync(createReq);

                // Then update the status to close it.
                task = new JObject();
                task["statecode"] = 1;
                task["statuscode"] = 5;
                HttpRequestMessage updateReq = new HttpRequestMessage(new HttpMethod("PATCH"), result.Headers.Location.LocalPath);
                updateReq.Content = new StringContent(JsonConvert.SerializeObject(
                    task, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore }), Encoding.UTF8, "application/json");

                result = await _proxy.SendAsync(updateReq);
            }
            else
            {
                // Create Task object to re-open completed task
                JObject task = new JObject();
                task["statecode"] = 0;
                task["statuscode"] = 3;

                HttpRequestMessage updateReq = new HttpRequestMessage(new HttpMethod("PATCH"), "tasks(" + activity.Id + ")");

                updateReq.Content = new StringContent(JsonConvert.SerializeObject(
                    task, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore }));
                updateReq.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

                HttpResponseMessage result = await _proxy.SendAsync(updateReq);

                // Create task object to have new values. Set to complete it.
                task = new JObject();
                task["subject"] = activity.Subject;

                task["actualstart"] = activity.ActualEnd;
                task["actualend"] = activity.ActualEnd;
                task["description"] = activity.Notes;
                task["statecode"] = 1;
                task["statuscode"] = 5;

                updateReq = new HttpRequestMessage(new HttpMethod("PATCH"), "tasks(" + activity.Id + ")");

                updateReq.Content = new StringContent(JsonConvert.SerializeObject(
                    task, new JsonSerializerSettings() { DefaultValueHandling = DefaultValueHandling.Ignore }));
                updateReq.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");

                result = await _proxy.SendAsync(updateReq);
            }
        }
        /// <summary>
        /// This method retrives a contact as late bound. 
        /// </summary>
        /// <param name="id">Contact Id</param>
        /// <returns>Contact Record</returns>
        public async Task<Contact> RetrieveContact(Guid id)
        {
            // Get AccessToken
            _proxy.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", await ADALHelper.GetTokenSilent());
            _proxy.DefaultRequestHeaders.Add("Prefer", "odata.include-annotations=\"*\""); 
            HttpResponseMessage retrieveRes = await _proxy.GetAsync("contacts(" + id + ")?$select=fullname,address1_composite,jobtitle,_parentcustomerid_value,emailaddress1,telephone1,entityimage");

            JToken result = JObject.Parse(retrieveRes.Content.ReadAsStringAsync().Result);

            Contact contact = new Contact()
            {
                Id = id,
                FullName = result["fullname"].ToString(),
                Address1 = (result["address1_composite"] != null) ? result["address1_composite"].ToString() : "",
                JobTitle = (result["jobtitle"] != null) ? result["jobtitle"].ToString() : "",                
                ParentCompany = (result["_parentcustomerid_value"] != null) ? result["*****@*****.**"].ToString() : "",
                Email1 = (result["emailaddress1"] != null) ? result["emailaddress1"].ToString() : "",
                Telephone1 = (result["telephone1"] != null) ? result["telephone1"].ToString() : "",
                EntityImage = (result["entityimage"].ToString() != "") ? System.Convert.FromBase64String(result["entityimage"].ToString()) : null
            };

            // Return the result
            return contact;
        }