/// <summary>
        /// Issues the notification events.
        /// </summary>
        /// <param name="gseResponse">The GetStreamingEvents response.</param>
        private void IssueNotificationEvents(GetStreamingEventsResponse gseResponse)
        {
            foreach (GetStreamingEventsResults.NotificationGroup events in gseResponse.Results.Notifications)
            {
                StreamingSubscription subscription = null;

                lock (this.lockObject)
                {
                    // Client can do any good or bad things in the below event handler
                    if (this.subscriptions != null && this.subscriptions.ContainsKey(events.SubscriptionId))
                    {
                        subscription = this.subscriptions[events.SubscriptionId];
                    }
                }

                if (subscription != null)
                {
                    NotificationEventArgs eventArgs = new NotificationEventArgs(
                        subscription,
                        events.Events);

                    if (this.OnNotificationEvent != null)
                    {
                        this.OnNotificationEvent(this, eventArgs);
                    }
                }
            }
        }
        /// <summary>
        /// Issues the general failure.
        /// </summary>
        /// <param name="gseResponse">The GetStreamingEvents response.</param>
        private void IssueGeneralFailure(GetStreamingEventsResponse gseResponse)
        {
            SubscriptionErrorEventArgs eventArgs = new SubscriptionErrorEventArgs(
                null,
                new ServiceResponseException(gseResponse));

            if (this.OnSubscriptionError != null)
            {
                this.OnSubscriptionError(this, eventArgs);
            }
        }
        /// <summary>
        /// Parses the response.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>Response object.</returns>
        internal override object ParseResponse(EwsServiceXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.ResponseMessages);

            GetStreamingEventsResponse response = new GetStreamingEventsResponse(this);

            response.LoadFromXml(reader, XmlElementNames.GetStreamingEventsResponseMessage);

            reader.ReadEndElementIfNecessary(XmlNamespace.Messages, XmlElementNames.ResponseMessages);

            return(response);
        }
        /// <summary>
        /// Issues the subscription failures.
        /// </summary>
        /// <param name="gseResponse">The GetStreamingEvents response.</param>
        private void IssueSubscriptionFailures(GetStreamingEventsResponse gseResponse)
        {
            ServiceResponseException exception = new ServiceResponseException(gseResponse);

            foreach (string id in gseResponse.ErrorSubscriptionIds)
            {
                StreamingSubscription subscription = null;

                lock (this.lockObject)
                {
                    // Client can do any good or bad things in the below event handler
                    if (this.subscriptions != null && this.subscriptions.ContainsKey(id))
                    {
                        subscription = this.subscriptions[id];
                    }
                }

                if (subscription != null)
                {
                    SubscriptionErrorEventArgs eventArgs = new SubscriptionErrorEventArgs(
                        subscription,
                        exception);

                    if (this.OnSubscriptionError != null)
                    {
                        this.OnSubscriptionError(this, eventArgs);
                    }
                }

                if (gseResponse.ErrorCode != ServiceError.ErrorMissedNotificationEvents)
                {
                    // Client can do any good or bad things in the above event handler
                    lock (this.lockObject)
                    {
                        if (this.subscriptions != null && this.subscriptions.ContainsKey(id))
                        {
                            // We are no longer servicing the subscription.
                            this.subscriptions.Remove(id);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Handles the service response object.
        /// </summary>
        /// <param name="response">The response.</param>
        private void HandleServiceResponseObject(object response)
        {
            GetStreamingEventsResponse gseResponse = response as GetStreamingEventsResponse;

            if (gseResponse == null)
            {
                throw new ArgumentException();
            }
            else
            {
                if (!hasFiredConnectionCompleted)
                {
                    OnConnectionCompleted?.Invoke(this, new EventArgs());
                    hasFiredConnectionCompleted = true;
                }
                if (gseResponse.Result == ServiceResult.Success || gseResponse.Result == ServiceResult.Warning)
                {
                    if (gseResponse.Results.Notifications.Count > 0)
                    {
                        // We got notifications; dole them out.
                        this.IssueNotificationEvents(gseResponse);
                    }
                    else
                    {
                        //// This was just a heartbeat, nothing to do here.
                    }
                }
                else if (gseResponse.Result == ServiceResult.Error)
                {
                    if (gseResponse.ErrorSubscriptionIds == null ||
                        gseResponse.ErrorSubscriptionIds.Count == 0)
                    {
                        // General error
                        this.IssueGeneralFailure(gseResponse);
                    }
                    else
                    {
                        // subscription-specific errors
                        this.IssueSubscriptionFailures(gseResponse);
                    }
                }
            }
        }
        /// <summary>
        /// Parses the response.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns>Response object.</returns>
        internal override object ParseResponse(EwsServiceXmlReader reader)
        {
            reader.ReadStartElement(XmlNamespace.Messages, XmlElementNames.ResponseMessages);

            GetStreamingEventsResponse response = new GetStreamingEventsResponse(this);
            response.LoadFromXml(reader, XmlElementNames.GetStreamingEventsResponseMessage);

            reader.ReadEndElementIfNecessary(XmlNamespace.Messages, XmlElementNames.ResponseMessages);

            return response;
        }
        /// <summary>
        /// Issues the notification events.
        /// </summary>
        /// <param name="gseResponse">The GetStreamingEvents response.</param>
        private void IssueNotificationEvents(GetStreamingEventsResponse gseResponse)
        {
            foreach (GetStreamingEventsResults.NotificationGroup events in gseResponse.Results.Notifications)
            {
                StreamingSubscription subscription = null;

                lock (this.lockObject)
                {
                    // Client can do any good or bad things in the below event handler
                    if (this.subscriptions != null && this.subscriptions.ContainsKey(events.SubscriptionId))
                    {
                        subscription = this.subscriptions[events.SubscriptionId];
                    }
                }

                if (subscription != null)
                {
                    NotificationEventArgs eventArgs = new NotificationEventArgs(
                        subscription,
                        events.Events);

                    if (this.OnNotificationEvent != null)
                    {
                        this.OnNotificationEvent(this, eventArgs);
                    }
                }
            }
        }
        /// <summary>
        /// Issues the general failure.
        /// </summary>
        /// <param name="gseResponse">The GetStreamingEvents response.</param>
        private void IssueGeneralFailure(GetStreamingEventsResponse gseResponse)
        {
            SubscriptionErrorEventArgs eventArgs = new SubscriptionErrorEventArgs(
                null,
                new ServiceResponseException(gseResponse));

            if (this.OnSubscriptionError != null)
            {
                this.OnSubscriptionError(this, eventArgs);
            }
        }
        /// <summary>
        /// Issues the subscription failures.
        /// </summary>
        /// <param name="gseResponse">The GetStreamingEvents response.</param>
        private void IssueSubscriptionFailures(GetStreamingEventsResponse gseResponse)
        {
            ServiceResponseException exception = new ServiceResponseException(gseResponse);

            foreach (string id in gseResponse.ErrorSubscriptionIds)
            {
                StreamingSubscription subscription = null;

                lock (this.lockObject)
                {
                    // Client can do any good or bad things in the below event handler
                    if (this.subscriptions != null && this.subscriptions.ContainsKey(id))
                    {
                        subscription = this.subscriptions[id];
                    }
                }

                if (subscription != null)
                {
                    SubscriptionErrorEventArgs eventArgs = new SubscriptionErrorEventArgs(
                        subscription,
                        exception);

                    if (this.OnSubscriptionError != null)
                    {
                        this.OnSubscriptionError(this, eventArgs);
                    }
                }

                if (gseResponse.ErrorCode != ServiceError.ErrorMissedNotificationEvents)
                {
                    // Client can do any good or bad things in the above event handler
                    lock (this.lockObject)
                    {
                        if (this.subscriptions != null && this.subscriptions.ContainsKey(id))
                        {
                            // We are no longer servicing the subscription.
                            this.subscriptions.Remove(id);
                        }
                    }
                }
            }
        }