Пример #1
0
        /// <summary>
        /// Reads the response.
        /// </summary>
        /// <param name="ewsXmlReader">The XML reader.</param>
        /// <param name="responseHeaders">HTTP response headers</param>
        /// <returns>Service response.</returns>
        protected object ReadResponse(EwsServiceXmlReader ewsXmlReader, WebHeaderCollection responseHeaders)
        {
            object serviceResponse;

            this.ReadPreamble(ewsXmlReader);
            ewsXmlReader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);
            this.ReadSoapHeader(ewsXmlReader);
            ewsXmlReader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);

            ewsXmlReader.ReadStartElement(XmlNamespace.Messages, this.GetResponseXmlElementName());

            if (responseHeaders != null)
            {
                serviceResponse = this.ParseResponse(ewsXmlReader, responseHeaders);
            }
            else
            {
                serviceResponse = this.ParseResponse(ewsXmlReader);
            }

            ewsXmlReader.ReadEndElementIfNecessary(XmlNamespace.Messages, this.GetResponseXmlElementName());

            ewsXmlReader.ReadEndElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);
            ewsXmlReader.ReadEndElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);
            return(serviceResponse);
        }
Пример #2
0
        /// <summary>
        /// Reads response elements from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal override void ReadElementsFromXml(EwsServiceXmlReader reader)
        {
            base.ReadElementsFromXml(reader);

            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.Attachments);
            if (!reader.IsEmptyElement)
            {
                reader.Read(XmlNodeType.Element);

                if (this.attachment == null)
                {
                    if (string.Equals(reader.LocalName, XmlElementNames.FileAttachment, StringComparison.OrdinalIgnoreCase))
                    {
                        this.attachment = new FileAttachment(reader.Service);
                    }
                    else if (string.Equals(reader.LocalName, XmlElementNames.ItemAttachment, StringComparison.OrdinalIgnoreCase))
                    {
                        this.attachment = new ItemAttachment(reader.Service);
                    }
                }

                if (this.attachment != null)
                {
                    this.attachment.LoadFromXml(reader, reader.LocalName);
                }

                reader.ReadEndElement(XmlNamespace.Messages, XmlElementNames.Attachments);
            }
        }
        /// <summary>
        /// Loads from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal void LoadFromXml(EwsServiceXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Types, XmlElementNames.Resolution);

            reader.ReadStartElement(XmlNamespace.Types, XmlElementNames.Mailbox);
            this.mailbox.LoadFromXml(reader, XmlElementNames.Mailbox);

            reader.Read();
            if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Contact))
            {
                this.contact = new Contact(this.owner.Session);

                // Contacts returned by ResolveNames should behave like Contact.Load with FirstClassPropertySet specified.
                this.contact.LoadFromXml(
                    reader,
                    true,                                               /* clearPropertyBag */
                    PropertySet.FirstClassProperties,
                    false);                                             /* summaryPropertiesOnly */

                reader.ReadEndElement(XmlNamespace.Types, XmlElementNames.Resolution);
            }
            else
            {
                reader.EnsureCurrentNodeIsEndElement(XmlNamespace.Types, XmlElementNames.Resolution);
            }
        }
        /// <summary>
        /// Reads response elements from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal override void ReadElementsFromXml(EwsServiceXmlReader reader)
        {
            this.Rooms.Clear();
            base.ReadElementsFromXml(reader);

            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.Rooms);

            if (!reader.IsEmptyElement)
            {
                // Because we don't have an element for count of returned object,
                // we have to test the element to determine if it is StartElement of return object or EndElement
                reader.Read();
                while (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Room))
                {
                    reader.Read(); // skip the start <Room>

                    EmailAddress emailAddress = new EmailAddress();
                    emailAddress.LoadFromXml(reader, XmlElementNames.RoomId);
                    this.Rooms.Add(emailAddress);

                    reader.ReadEndElement(XmlNamespace.Types, XmlElementNames.Room);
                    reader.Read();
                }

                reader.EnsureCurrentNodeIsEndElement(XmlNamespace.Messages, XmlElementNames.Rooms);
            }
        }
Пример #5
0
        /// <summary>
        /// Loads from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal void LoadFromXml(EwsServiceXmlReader reader)
        {
            reader.EnsureCurrentNodeIsStartElement(XmlNamespace.Types, XmlElementNames.Duration);

            this.startTime = reader.ReadElementValueAsDateTime(XmlNamespace.Types, XmlElementNames.StartTime).Value;
            this.endTime   = reader.ReadElementValueAsDateTime(XmlNamespace.Types, XmlElementNames.EndTime).Value;

            reader.ReadEndElement(XmlNamespace.Types, XmlElementNames.Duration);
        }
        /// <summary>
        /// Reads the response.
        /// </summary>
        /// <param name="ewsXmlReader">The XML reader.</param>
        /// <returns>Service response.</returns>
        protected object ReadResponse(EwsServiceXmlReader ewsXmlReader)
        {
            object serviceResponse;

            this.ReadPreamble(ewsXmlReader);
            ewsXmlReader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);
            this.ReadSoapHeader(ewsXmlReader);
            ewsXmlReader.ReadStartElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);

            ewsXmlReader.ReadStartElement(XmlNamespace.Messages, this.GetResponseXmlElementName());

            serviceResponse = this.ParseResponse(ewsXmlReader);

            ewsXmlReader.ReadEndElementIfNecessary(XmlNamespace.Messages, this.GetResponseXmlElementName());

            ewsXmlReader.ReadEndElement(XmlNamespace.Soap, XmlElementNames.SOAPBodyElementName);
            ewsXmlReader.ReadEndElement(XmlNamespace.Soap, XmlElementNames.SOAPEnvelopeElementName);
            return(serviceResponse);
        }
Пример #7
0
        /// <summary>
        /// Reads response elements from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal override void ReadElementsFromXml(EwsServiceXmlReader reader)
        {
            base.ReadElementsFromXml(reader);

            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.Attachments);

            reader.Read(XmlNodeType.Element);
            this.attachment.LoadFromXml(reader, reader.LocalName);

            reader.ReadEndElement(XmlNamespace.Messages, XmlElementNames.Attachments);
        }
Пример #8
0
        /// <summary>
        /// Loads from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="xmlElementName">Name of the XML element.</param>
        internal void LoadFromXml(EwsServiceXmlReader reader, string xmlElementName)
        {
            reader.EnsureCurrentNodeIsStartElement(XmlNamespace.Types, xmlElementName);

            if (reader.HasAttributes)
            {
                this.culture = reader.ReadAttributeValue("xml:lang");
            }

            this.message = reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.Message);

            reader.ReadEndElement(XmlNamespace.Types, xmlElementName);
        }
        /// <summary>
        /// Parses the response.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>Response object.</returns>
        internal override object ParseResponse(EwsServiceXmlReader reader)
        {
            GetUserAvailabilityResults serviceResponse = new GetUserAvailabilityResults();

            if (this.IsFreeBusyViewRequested)
            {
                serviceResponse.AttendeesAvailability = new ServiceResponseCollection <AttendeeAvailability>();

                reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.FreeBusyResponseArray);

                do
                {
                    reader.Read();

                    if (reader.IsStartElement(XmlNamespace.Messages, XmlElementNames.FreeBusyResponse))
                    {
                        AttendeeAvailability freeBusyResponse = new AttendeeAvailability();

                        freeBusyResponse.LoadFromXml(reader, XmlElementNames.ResponseMessage);

                        if (freeBusyResponse.ErrorCode == ServiceError.NoError)
                        {
                            freeBusyResponse.LoadFreeBusyViewFromXml(reader, this.Options.RequestedFreeBusyView);
                        }

                        serviceResponse.AttendeesAvailability.Add(freeBusyResponse);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Messages, XmlElementNames.FreeBusyResponseArray));
            }

            if (this.IsSuggestionsViewRequested)
            {
                serviceResponse.SuggestionsResponse = new SuggestionsResponse();

                reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.SuggestionsResponse);

                serviceResponse.SuggestionsResponse.LoadFromXml(reader, XmlElementNames.ResponseMessage);

                if (serviceResponse.SuggestionsResponse.ErrorCode == ServiceError.NoError)
                {
                    serviceResponse.SuggestionsResponse.LoadSuggestedDaysFromXml(reader);
                }

                reader.ReadEndElement(XmlNamespace.Messages, XmlElementNames.SuggestionsResponse);
            }

            return(serviceResponse);
        }
        /// <summary>
        /// Loads from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal void LoadFromXml(EwsServiceXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.ResolutionSet);

            int totalItemsInView = reader.ReadAttributeValue <int>(XmlAttributeNames.TotalItemsInView);

            this.includesAllResolutions = reader.ReadAttributeValue <bool>(XmlAttributeNames.IncludesLastItemInRange);

            for (int i = 0; i < totalItemsInView; i++)
            {
                NameResolution nameResolution = new NameResolution(this);

                nameResolution.LoadFromXml(reader);

                this.items.Add(nameResolution);
            }

            reader.ReadEndElement(XmlNamespace.Messages, XmlElementNames.ResolutionSet);
        }
Пример #11
0
        /// <summary>
        /// Reads response elements from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal override void ReadElementsFromXml(EwsServiceXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.RootFolder);

            this.results.TotalCount    = reader.ReadAttributeValue <int>(XmlAttributeNames.TotalItemsInView);
            this.results.MoreAvailable = !reader.ReadAttributeValue <bool>(XmlAttributeNames.IncludesLastItemInRange);

            // Ignore IndexedPagingOffset attribute if MoreAvailable is false.
            this.results.NextPageOffset = results.MoreAvailable ? reader.ReadNullableAttributeValue <int>(XmlAttributeNames.IndexedPagingOffset) : null;

            reader.ReadStartElement(XmlNamespace.Types, XmlElementNames.Folders);
            if (!reader.IsEmptyElement)
            {
                do
                {
                    reader.Read();

                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        Folder folder = EwsUtilities.CreateEwsObjectFromXmlElementName <Folder>(reader.Service, reader.LocalName);

                        if (folder == null)
                        {
                            reader.SkipCurrentElement();
                        }
                        else
                        {
                            folder.LoadFromXml(
                                reader,
                                true,         /* clearPropertyBag */
                                this.propertySet,
                                true /* summaryPropertiesOnly */);

                            this.results.Folders.Add(folder);
                        }
                    }
                }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Folders));
            }

            reader.ReadEndElement(XmlNamespace.Messages, XmlElementNames.RootFolder);
        }
Пример #12
0
        /// <summary>
        /// Loads from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal void LoadFromXml(EwsServiceXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.DLExpansion);
            if (!reader.IsEmptyElement)
            {
                int totalItemsInView = reader.ReadAttributeValue <int>(XmlAttributeNames.TotalItemsInView);
                this.includesAllMembers = reader.ReadAttributeValue <bool>(XmlAttributeNames.IncludesLastItemInRange);

                for (int i = 0; i < totalItemsInView; i++)
                {
                    EmailAddress emailAddress = new EmailAddress();

                    reader.ReadStartElement(XmlNamespace.Types, XmlElementNames.Mailbox);
                    emailAddress.LoadFromXml(reader, XmlElementNames.Mailbox);

                    this.members.Add(emailAddress);
                }

                reader.ReadEndElement(XmlNamespace.Messages, XmlElementNames.DLExpansion);
            }
        }
Пример #13
0
        /// <summary>
        /// Reads response elements from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal override void ReadElementsFromXml(EwsServiceXmlReader reader)
        {
            base.ReadElementsFromXml(reader);

            reader.ReadServiceObjectsCollectionFromXml <Item>(
                XmlElementNames.Items,
                this.GetObjectInstance,
                false,  /* clearPropertyBag */
                null,   /* requestedPropertySet */
                false); /* summaryPropertiesOnly */

            // ConflictResults was only added in 2007 SP1 so if this was a 2007 RTM request we shouldn't expect to find the element
            if (!reader.Service.Exchange2007CompatibilityMode)
            {
                reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.ConflictResults);
                this.conflictCount = reader.ReadElementValue <int>(XmlNamespace.Types, XmlElementNames.Count);
                reader.ReadEndElement(XmlNamespace.Messages, XmlElementNames.ConflictResults);
            }

            // If UpdateItem returned an item that has the same Id as the item that
            // is being updated, this is a "normal" UpdateItem operation, and we need
            // to update the ChangeKey of the item being updated with the one that was
            // returned. Also set returnedItem to indicate that no new item was returned.
            //
            // Otherwise, this in a "special" UpdateItem operation, such as a recurring
            // task marked as complete (the returned item in that case is the one-off
            // task that represents the completed instance).
            //
            // Note that there can be no returned item at all, as in an UpdateItem call
            // with MessageDisposition set to SendOnly or SendAndSaveCopy.
            if (this.returnedItem != null)
            {
                if (this.item.Id.UniqueId == this.returnedItem.Id.UniqueId)
                {
                    this.item.Id.ChangeKey = this.returnedItem.Id.ChangeKey;
                    this.returnedItem      = null;
                }
            }
        }
Пример #14
0
        /// <summary>
        /// Tries to read element from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>True if element was read.</returns>
        internal override bool TryReadElementFromXml(EwsServiceXmlReader reader)
        {
            switch (reader.LocalName)
            {
            case XmlElementNames.AssignCategories:
                this.assignCategories.LoadFromXml(reader, reader.LocalName);
                return(true);

            case XmlElementNames.CopyToFolder:
                reader.ReadStartElement(XmlNamespace.NotSpecified, XmlElementNames.FolderId);
                this.copyToFolder = new FolderId();
                this.copyToFolder.LoadFromXml(reader, XmlElementNames.FolderId);
                reader.ReadEndElement(XmlNamespace.NotSpecified, XmlElementNames.CopyToFolder);
                return(true);

            case XmlElementNames.Delete:
                this.delete = reader.ReadElementValue <bool>();
                return(true);

            case XmlElementNames.ForwardAsAttachmentToRecipients:
                this.forwardAsAttachmentToRecipients.LoadFromXml(reader, reader.LocalName);
                return(true);

            case XmlElementNames.ForwardToRecipients:
                this.forwardToRecipients.LoadFromXml(reader, reader.LocalName);
                return(true);

            case XmlElementNames.MarkImportance:
                this.markImportance = reader.ReadElementValue <Importance>();
                return(true);

            case XmlElementNames.MarkAsRead:
                this.markAsRead = reader.ReadElementValue <bool>();
                return(true);

            case XmlElementNames.MoveToFolder:
                reader.ReadStartElement(XmlNamespace.NotSpecified, XmlElementNames.FolderId);
                this.moveToFolder = new FolderId();
                this.moveToFolder.LoadFromXml(reader, XmlElementNames.FolderId);
                reader.ReadEndElement(XmlNamespace.NotSpecified, XmlElementNames.MoveToFolder);
                return(true);

            case XmlElementNames.PermanentDelete:
                this.permanentDelete = reader.ReadElementValue <bool>();
                return(true);

            case XmlElementNames.RedirectToRecipients:
                this.redirectToRecipients.LoadFromXml(reader, reader.LocalName);
                return(true);

            case XmlElementNames.SendSMSAlertToRecipients:
                EmailAddressCollection smsRecipientCollection = new EmailAddressCollection(XmlElementNames.Address);
                smsRecipientCollection.LoadFromXml(reader, reader.LocalName);
                this.sendSMSAlertToRecipients = ConvertSMSRecipientsFromEmailAddressCollectionToMobilePhoneCollection(smsRecipientCollection);
                return(true);

            case XmlElementNames.ServerReplyWithMessage:
                this.serverReplyWithMessage = new ItemId();
                this.serverReplyWithMessage.LoadFromXml(reader, reader.LocalName);
                return(true);

            case XmlElementNames.StopProcessingRules:
                this.stopProcessingRules = reader.ReadElementValue <bool>();
                return(true);

            default:
                return(false);
            }
        }
Пример #15
0
        /// <summary>
        /// Reads the SOAP fault.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>SOAP fault details.</returns>
        protected SoapFaultDetails ReadSoapFault(EwsServiceXmlReader reader)
        {
            SoapFaultDetails soapFaultDetails = null;

            try
            {
                this.ReadXmlDeclaration(reader);

                reader.Read();
                if (!reader.IsStartElement() || (reader.LocalName != XmlElementNames.SOAPEnvelopeElementName))
                {
                    return(soapFaultDetails);
                }

                // EWS can sometimes return SOAP faults using the SOAP 1.2 namespace. Get the
                // namespace URI from the envelope element and use it for the rest of the parsing.
                // If it's not 1.1 or 1.2, we can't continue.
                XmlNamespace soapNamespace = EwsUtilities.GetNamespaceFromUri(reader.NamespaceUri);
                if (soapNamespace == XmlNamespace.NotSpecified)
                {
                    return(soapFaultDetails);
                }

                reader.Read();

                // EWS doesn't always return a SOAP header. If this response contains a header element,
                // read the server version information contained in the header.
                if (reader.IsStartElement(soapNamespace, XmlElementNames.SOAPHeaderElementName))
                {
                    do
                    {
                        reader.Read();

                        if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.ServerVersionInfo))
                        {
                            this.Service.ServerInfo = ExchangeServerInfo.Parse(reader);
                        }
                    }while (!reader.IsEndElement(soapNamespace, XmlElementNames.SOAPHeaderElementName));

                    // Queue up the next read
                    reader.Read();
                }

                // Parse the fault element contained within the SOAP body.
                if (reader.IsStartElement(soapNamespace, XmlElementNames.SOAPBodyElementName))
                {
                    do
                    {
                        reader.Read();

                        // Parse Fault element
                        if (reader.IsStartElement(soapNamespace, XmlElementNames.SOAPFaultElementName))
                        {
                            soapFaultDetails = SoapFaultDetails.Parse(reader, soapNamespace);
                        }
                    }while (!reader.IsEndElement(soapNamespace, XmlElementNames.SOAPBodyElementName));
                }

                reader.ReadEndElement(soapNamespace, XmlElementNames.SOAPEnvelopeElementName);
            }
            catch (XmlException)
            {
                // If response doesn't contain a valid SOAP fault, just ignore exception and
                // return null for SOAP fault details.
            }

            return(soapFaultDetails);
        }
Пример #16
0
        /// <summary>
        /// Reads response elements from XML.
        /// </summary>
        /// <param name="reader">The reader.</param>
        internal override void ReadElementsFromXml(EwsServiceXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.RootFolder);

            int  totalItemsInView   = reader.ReadAttributeValue <int>(XmlAttributeNames.TotalItemsInView);
            bool moreItemsAvailable = !reader.ReadAttributeValue <bool>(XmlAttributeNames.IncludesLastItemInRange);

            // Ignore IndexedPagingOffset attribute if moreItemsAvailable is false.
            int?nextPageOffset = moreItemsAvailable ? reader.ReadNullableAttributeValue <int>(XmlAttributeNames.IndexedPagingOffset) : null;

            if (!this.isGrouped)
            {
                this.results                = new FindItemsResults <TItem>();
                this.results.TotalCount     = totalItemsInView;
                this.results.NextPageOffset = nextPageOffset;
                this.results.MoreAvailable  = moreItemsAvailable;
                InternalReadItemsFromXml(
                    reader,
                    this.propertySet,
                    this.results.Items);
            }
            else
            {
                this.groupedFindResults                = new GroupedFindItemsResults <TItem>();
                this.groupedFindResults.TotalCount     = totalItemsInView;
                this.groupedFindResults.NextPageOffset = nextPageOffset;
                this.groupedFindResults.MoreAvailable  = moreItemsAvailable;

                reader.ReadStartElement(XmlNamespace.Types, XmlElementNames.Groups);

                if (!reader.IsEmptyElement)
                {
                    do
                    {
                        reader.Read();

                        if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.GroupedItems))
                        {
                            string groupIndex = reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.GroupIndex);

                            List <TItem> itemList = new List <TItem>();
                            InternalReadItemsFromXml(
                                reader,
                                this.propertySet,
                                itemList);

                            reader.ReadEndElement(XmlNamespace.Types, XmlElementNames.GroupedItems);

                            this.groupedFindResults.ItemGroups.Add(new ItemGroup <TItem>(groupIndex, itemList));
                        }
                    }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Groups));
                }
            }

            reader.ReadEndElement(XmlNamespace.Messages, XmlElementNames.RootFolder);

            reader.Read();

            if (reader.IsStartElement(XmlNamespace.Messages, XmlElementNames.HighlightTerms) &&
                !reader.IsEmptyElement)
            {
                do
                {
                    reader.Read();

                    if (reader.NodeType == XmlNodeType.Element)
                    {
                        HighlightTerm term = new HighlightTerm();

                        term.LoadFromXml(
                            reader,
                            XmlNamespace.Types,
                            XmlElementNames.HighlightTerm);
                        this.results.HighlightTerms.Add(term);
                    }
                }while (!reader.IsEndElement(XmlNamespace.Messages, XmlElementNames.HighlightTerms));
            }
        }
Пример #17
0
        /// <summary>
        /// Load from xml
        /// </summary>
        /// <param name="reader">The reader</param>
        /// <returns>Search result object</returns>
        internal static SearchMailboxesResult LoadFromXml(EwsServiceXmlReader reader)
        {
            SearchMailboxesResult searchResult = new SearchMailboxesResult();

            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.SearchMailboxesResult);

            List <MailboxQuery> searchQueries = new List <MailboxQuery>();

            do
            {
                reader.Read();
                if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.SearchQueries))
                {
                    reader.ReadStartElement(XmlNamespace.Types, XmlElementNames.MailboxQuery);
                    string query = reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.Query);
                    reader.ReadStartElement(XmlNamespace.Types, XmlElementNames.MailboxSearchScopes);
                    List <MailboxSearchScope> mailboxSearchScopes = new List <MailboxSearchScope>();
                    do
                    {
                        reader.Read();
                        if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.MailboxSearchScope))
                        {
                            string mailbox = reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.Mailbox);
                            reader.ReadStartElement(XmlNamespace.Types, XmlElementNames.SearchScope);
                            string searchScope = reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.SearchScope);
                            reader.ReadEndElement(XmlNamespace.Types, XmlElementNames.MailboxSearchScope);
                            mailboxSearchScopes.Add(new MailboxSearchScope(mailbox, (MailboxSearchLocation)Enum.Parse(typeof(MailboxSearchLocation), searchScope)));
                        }
                    }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.MailboxSearchScopes));
                    reader.ReadEndElementIfNecessary(XmlNamespace.Types, XmlElementNames.MailboxSearchScopes);
                    searchQueries.Add(new MailboxQuery(query, mailboxSearchScopes.ToArray()));
                }
            }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.SearchQueries));
            reader.ReadEndElementIfNecessary(XmlNamespace.Types, XmlElementNames.SearchQueries);
            searchResult.SearchQueries = searchQueries.ToArray();

            searchResult.ResultType    = (SearchResultType)Enum.Parse(typeof(SearchResultType), reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.ResultType));
            searchResult.ItemCount     = int.Parse(reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.ItemCount));
            searchResult.Size          = ulong.Parse(reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.Size));
            searchResult.PageItemCount = int.Parse(reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.PageItemCount));
            searchResult.PageItemSize  = ulong.Parse(reader.ReadElementValue(XmlNamespace.Types, XmlElementNames.PageItemSize));

            do
            {
                reader.Read();
                if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.KeywordStats))
                {
                    searchResult.KeywordStats = LoadKeywordStatsXml(reader);
                }

                if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Items))
                {
                    searchResult.PreviewItems = LoadPreviewItemsXml(reader);
                }

                if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.FailedMailboxes))
                {
                    searchResult.FailedMailboxes = FailedSearchMailbox.LoadFailedMailboxesXml(XmlNamespace.Types, reader);
                }

                if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Refiners))
                {
                    List <SearchRefinerItem> refiners = new List <SearchRefinerItem>();
                    do
                    {
                        reader.Read();
                        if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.Refiner))
                        {
                            refiners.Add(SearchRefinerItem.LoadFromXml(reader));
                        }
                    }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.Refiners));
                    if (refiners.Count > 0)
                    {
                        searchResult.Refiners = refiners.ToArray();
                    }
                }

                if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.MailboxStats))
                {
                    List <MailboxStatisticsItem> mailboxStats = new List <MailboxStatisticsItem>();
                    do
                    {
                        reader.Read();
                        if (reader.IsStartElement(XmlNamespace.Types, XmlElementNames.MailboxStat))
                        {
                            mailboxStats.Add(MailboxStatisticsItem.LoadFromXml(reader));
                        }
                    }while (!reader.IsEndElement(XmlNamespace.Types, XmlElementNames.MailboxStats));
                    if (mailboxStats.Count > 0)
                    {
                        searchResult.MailboxStats = mailboxStats.ToArray();
                    }
                }
            }while (!reader.IsEndElement(XmlNamespace.Messages, XmlElementNames.SearchMailboxesResult));

            return(searchResult);
        }