/**
   * Issues the subscription failures.
   *
   * @param gseResponse The GetStreamingEvents response.
   */
  private void issueSubscriptionFailures(GetStreamingEventsResponse gseResponse) {
    ServiceResponseException exception = new ServiceResponseException(gseResponse);

    for (String id : gseResponse.getErrorSubscriptionIds()) {
      StreamingSubscription subscription = null;

      synchronized (this) {
        // Client can do any good or bad things in the below event
        // handler
        if (this.subscriptions != null && this.subscriptions.containsKey(id)) {
          subscription = this.subscriptions.get(id);
        }
      }
      if (subscription != null) {
        SubscriptionErrorEventArgs eventArgs =
            new SubscriptionErrorEventArgs(subscription, exception);

        if (!onSubscriptionError.isEmpty()) {
          for (ISubscriptionErrorDelegate subError : onSubscriptionError) {
            subError.subscriptionErrorDelegate(this, eventArgs);
          }
        }
      }
      if (gseResponse.getErrorCode() != ServiceError.ErrorMissedNotificationEvents) {
        // Client can do any good or bad things in the above event
        // handler
        synchronized (this) {
          if (this.subscriptions != null && this.subscriptions.containsKey(id)) {
            // We are no longer servicing the subscription.
            this.subscriptions.remove(id);
          }
        }
      }
    }
  }
  /**
   * Handles the service response object.
   *
   * @param response The response.
   * @throws microsoft.exchange.webservices.data.exception.ArgumentException
   */
  private void handleServiceResponseObject(Object response) throws ArgumentException {
    GetStreamingEventsResponse gseResponse = (GetStreamingEventsResponse) response;

    if (gseResponse == null) {
      throw new ArgumentException();
    } else {
      if (gseResponse.getResult() == ServiceResult.Success
          || gseResponse.getResult() == ServiceResult.Warning) {
        if (gseResponse.getResults().getNotifications().size() > 0) {
          // We got notification; dole them out.
          this.issueNotificationEvents(gseResponse);
        } else {
          // // This was just a heartbeat, nothing to do here.
        }
      } else if (gseResponse.getResult() == ServiceResult.Error) {
        if (gseResponse.getErrorSubscriptionIds() == null
            || gseResponse.getErrorSubscriptionIds().size() == 0) {
          // General error
          this.issueGeneralFailure(gseResponse);
        } else {
          // subscription-specific errors
          this.issueSubscriptionFailures(gseResponse);
        }
      }
    }
  }
  /**
   * Issues the notification events.
   *
   * @param gseResponse The GetStreamingEvents response.
   */
  private void issueNotificationEvents(GetStreamingEventsResponse gseResponse) {

    for (GetStreamingEventsResults.NotificationGroup events :
        gseResponse.getResults().getNotifications()) {
      StreamingSubscription subscription = null;

      synchronized (this) {
        // 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.get(events.subscriptionId);
        }
      }
      if (subscription != null) {
        NotificationEventArgs eventArgs = new NotificationEventArgs(subscription, events.events);

        if (!onNotificationEvent.isEmpty()) {
          for (INotificationEventDelegate notifyEvent : onNotificationEvent) {
            notifyEvent.notificationEventDelegate(this, eventArgs);
          }
        }
      }
    }
  }