/// <summary>
        /// Synchronizes the contact from Exchange to sevDesk.
        /// </summary>
        /// <param name="exchangeUserId">The ID of the Exchange user.</param>
        /// <param name="exchangeContact">The Exchange contact.</param>
        /// <param name="sevDeskContact">The sevDesk contact.</param>
        /// <returns>Returns the sync state of this operation.</returns>
        private async Task <ContactSyncState> SynchronizeContactFromExchangeToSevDeskAsync(string exchangeUserId, Exchange.Contacts.Contact exchangeContact, SevDesk.Contacts.Person sevDeskContact)
        {
            // Updates the contact
            SevDesk.Contacts.Contact updatedSevDeskContact = await this.SevDeskService.UpdateContactAsync(sevDeskContact.Id, new SevDesk.Contacts.PersonOptions
            {
                AcademicTitle  = exchangeContact.Title,
                Birthday       = exchangeContact.Birthday,
                CategoryId     = sevDeskContact.Category?.Id,
                CustomerNumber = sevDeskContact.CustomerNumber,
                Description    = exchangeContact.PersonalNotes,
                Gender         = sevDeskContact.Gender,
                OrganizationId = sevDeskContact.Organization?.Id,
                Position       = exchangeContact.JobTitle,
                FirstName      = exchangeContact.FirstName,
                LastName       = exchangeContact.LastName
            });

            // returns the new sync state
            return(new ContactSyncState
            {
                ExchangeContactId = exchangeContact.Id,
                ExchangeContactLastModifiedDateTime = exchangeContact.LastModifiedDateTime,
                ExchangeUserId = exchangeUserId,
                SevDeskContactId = updatedSevDeskContact.Id,
                SevDeskContactUpdateDateTime = updatedSevDeskContact.UpdateDateTime
            });
        }
        /// <summary>
        /// Synchronizes the contact from sevDesk to Exchange.
        /// </summary>
        /// <param name="sevDeskContact">The sevDesk contact.</param>
        /// <param name="exchangeUserId">The ID of the Exchange user.</param>
        /// <param name="exchangeContactId">The ID of the Exchange contact.</param>
        /// <returns>Returns the sync state of this operation.</returns>
        private async Task <ContactSyncState> SynchronizeContactFromSevDeskToExchangeAsync(SevDesk.Contacts.Person sevDeskContact, string exchangeUserId, string exchangeContactId)
        {
            // Gets the addresses and communication ways of the sevDesk contact
            IEnumerable <SevDesk.Addresses.Address> contactAddresses = await this.SevDeskService.GetAddressesAsync(sevDeskContact.Id);

            IEnumerable <SevDesk.Addresses.Address> organizationAddresses = sevDeskContact.Organization == null ? new List <SevDesk.Addresses.Address>() : await this.SevDeskService.GetAddressesAsync(sevDeskContact.Organization.Id);

            IEnumerable <SevDesk.CommunicationWays.CommunicationWay> contactCommunicationWays = await this.SevDeskService.GetCommunicationWaysAsync(sevDeskContact.Id);

            IEnumerable <SevDesk.CommunicationWays.CommunicationWay> organizationCommunicationWays = sevDeskContact.Organization == null ? new List <SevDesk.CommunicationWays.CommunicationWay>() : await this.SevDeskService.GetCommunicationWaysAsync(sevDeskContact.Organization.Id);

            // Gets the home address
            SevDesk.Addresses.Address homeAddress = contactAddresses.FirstOrDefault(address => address.Category is SevDesk.Categories.PrivateAddressCategory);
            if (homeAddress == null)
            {
                homeAddress = organizationAddresses.FirstOrDefault(address => address.Category is SevDesk.Categories.PrivateAddressCategory);
            }

            // Gets the business address
            SevDesk.Addresses.Address businessAddress = contactAddresses.FirstOrDefault(address => address.Category is SevDesk.Categories.WorkAddressCategory);
            if (businessAddress == null)
            {
                businessAddress = organizationAddresses.FirstOrDefault(address => address.Category is SevDesk.Categories.WorkAddressCategory);
            }

            // Gets the home phone numbers
            List <string> homePhoneNumbers = new List <string>();

            homePhoneNumbers.AddRange(contactCommunicationWays.OfType <SevDesk.CommunicationWays.PhoneNumber>().Where(phoneNumber => phoneNumber.Kind is SevDesk.CommunicationWayKinds.PrivateKind).Select(phoneNumber => phoneNumber.Value));
            homePhoneNumbers.AddRange(organizationCommunicationWays.OfType <SevDesk.CommunicationWays.PhoneNumber>().Where(phoneNumber => phoneNumber.Kind is SevDesk.CommunicationWayKinds.PrivateKind).Select(phoneNumber => phoneNumber.Value));
            homePhoneNumbers = homePhoneNumbers.Distinct().ToList();

            // Gets the mobile phone number
            string mobilePhoneNumber = contactCommunicationWays.OfType <SevDesk.CommunicationWays.MobilePhoneNumber>().Where(phoneNumber => phoneNumber.Kind is SevDesk.CommunicationWayKinds.MobileKind).OrderBy(phoneNumber => phoneNumber.IsPrimary).Select(phoneNumber => phoneNumber.Value).FirstOrDefault();

            if (mobilePhoneNumber == null)
            {
                mobilePhoneNumber = organizationCommunicationWays.OfType <SevDesk.CommunicationWays.MobilePhoneNumber>().Where(phoneNumber => phoneNumber.Kind is SevDesk.CommunicationWayKinds.MobileKind).OrderBy(phoneNumber => phoneNumber.IsPrimary).Select(phoneNumber => phoneNumber.Value).FirstOrDefault();
            }

            // Gets the business website
            string businessWebsite = contactCommunicationWays.OfType <SevDesk.CommunicationWays.Website>().Where(website => website.Kind is SevDesk.CommunicationWayKinds.WorkKind).OrderBy(website => website.IsPrimary).Select(website => website.Value).FirstOrDefault();

            if (businessWebsite == null)
            {
                businessWebsite = organizationCommunicationWays.OfType <SevDesk.CommunicationWays.Website>().Where(website => website.Kind is SevDesk.CommunicationWayKinds.WorkKind).OrderBy(website => website.IsPrimary).Select(website => website.Value).FirstOrDefault();
            }

            // Gets the business numbers
            List <string> businessPhoneNumbers = new List <string>();

            businessPhoneNumbers.AddRange(contactCommunicationWays.OfType <SevDesk.CommunicationWays.PhoneNumber>().Where(phoneNumber => phoneNumber.Kind is SevDesk.CommunicationWayKinds.WorkKind).Select(phoneNumber => phoneNumber.Value));
            businessPhoneNumbers.AddRange(organizationCommunicationWays.OfType <SevDesk.CommunicationWays.PhoneNumber>().Where(phoneNumber => phoneNumber.Kind is SevDesk.CommunicationWayKinds.WorkKind).Select(phoneNumber => phoneNumber.Value));
            businessPhoneNumbers = businessPhoneNumbers.Distinct().ToList();

            // Gets the business numbers
            List <Exchange.Contacts.EmailAddress> emailAddresses = new List <Exchange.Contacts.EmailAddress>();

            emailAddresses.AddRange(contactCommunicationWays.OfType <SevDesk.CommunicationWays.EmailAddress>().Select(emailAddress => new Exchange.Contacts.EmailAddress($"{sevDeskContact.FirstName} {sevDeskContact.LastName}", emailAddress.Value)));
            emailAddresses.AddRange(organizationCommunicationWays.OfType <SevDesk.CommunicationWays.EmailAddress>().Select(emailAddress => new Exchange.Contacts.EmailAddress($"{sevDeskContact.Organization.Name}", emailAddress.Value)));
            emailAddresses = emailAddresses.Distinct().ToList();

            // Updates the contact
            Exchange.Contacts.Contact exchangeContact = await this.ExchangeService.UpdateContactAsync(exchangeUserId, exchangeContactId, new Exchange.Contacts.ContactOptions
            {
                FirstName            = sevDeskContact.FirstName,
                LastName             = sevDeskContact.LastName,
                Birthday             = sevDeskContact.Birthday,
                BusinessAddress      = businessAddress == null ? null : new Exchange.Contacts.Address(businessAddress.Street, businessAddress.ZipCode, businessAddress.City, null, businessAddress.Country.Name),
                HomeAddress          = homeAddress == null ? null : new Exchange.Contacts.Address(homeAddress.Street, homeAddress.ZipCode, homeAddress.City, null, homeAddress.Country.Name),
                CompanyName          = sevDeskContact.Organization?.Name,
                JobTitle             = sevDeskContact.Position,
                PersonalNotes        = sevDeskContact.Description,
                Title                = sevDeskContact.AcademicTitle,
                BusinessPhoneNumbers = businessPhoneNumbers,
                HomePhoneNumbers     = homePhoneNumbers,
                MobilePhoneNumber    = mobilePhoneNumber,
                BusinessWebsite      = businessWebsite,
                EmailAddresses       = emailAddresses
            });

            // returns the new sync state
            return(new ContactSyncState
            {
                ExchangeContactId = exchangeContact.Id,
                ExchangeContactLastModifiedDateTime = exchangeContact.LastModifiedDateTime,
                ExchangeUserId = exchangeUserId,
                SevDeskContactId = sevDeskContact.Id,
                SevDeskContactUpdateDateTime = sevDeskContact.UpdateDateTime
            });
        }