/// <summary>
        /// Parses the specified exception.
        /// </summary>
        /// <param name="ex">Exception to parse.</param>
        /// <returns>Parsed exception.</returns>
        /// <exception cref="ArgumentNullException">Exception is null.</exception>
        /// <exception cref="ArgumentException">Exception is not of type InvalidOperationException.</exception>
        public static ParsedException Parse(Exception ex)
        {
            if (ex == null)
            {
                throw new ArgumentNullException("ex");
            }

            if (!(ex is InvalidOperationException))
            {
                throw new ArgumentException("Exception is not of type InvalidOperationException", "ex");
            }

            ParsedException parsedException = new ParsedException();

            string messageToBeParsed = ex.Message;

            if (ex.InnerException != null)
            {
                messageToBeParsed = ex.InnerException.Message;
            }

            try
            {
                StringReader     stringReader = new StringReader(messageToBeParsed);
                XmlErrorResponse errorObject  =
                    ParsedException.xmlSerializer.Deserialize(stringReader) as XmlErrorResponse;
                parsedException = new ParsedException(errorObject);
            }
            catch (InvalidOperationException)
            {
            }

            if (String.IsNullOrEmpty(parsedException.Code))
            {
                parsedException.Code = messageToBeParsed;
            }

            return(parsedException);
        }
        /// <summary>
        /// Delegate to invoke the specified operation, and retry if necessary.
        /// </summary>
        /// <param name="operation">Operation to invoke.</param>
        private void InvokeOperationWithRetry(Action operation)
        {
            int retryCount = Constants.MaxRetryAttempts;

            while (retryCount > 0)
            {
                try
                {
                    operation();

                    // Operation was successful
                    retryCount = 0;
                }
                catch (InvalidOperationException ex)
                {
                    // Operation not successful

                    // De-serialize error message to check the error code from AzureAD Service
                    ParsedException parsedException = ParsedException.Parse(ex);
                    if (parsedException == null)
                    {
                        // Could not parse the exception so it wasn't in the format of DataServiceException
                        throw;
                    }

                    // Look at the error code to determine if we want to retry on this exception
                    switch (parsedException.Code)
                    {
                    // These are the errors we don't want to retry on
                    // Please look at the descriptions for details about each of these
                    case Constants.MessageIdAuthorizationIdentityDisabled:
                    case Constants.MessageIdAuthorizationIdentityNotFound:
                    case Constants.MessageIdAuthorizationRequestDenied:
                    case Constants.MessageIdBadRequest:
                    case Constants.MessageIdContractVersionHeaderMissing:
                    case Constants.MessageIdHeaderNotSupported:
                    case Constants.MessageIdInternalServerError:
                    case Constants.MessageIdInvalidDataContractVersion:
                    case Constants.MessageIdInvalidReplicaSessionKey:
                    case Constants.MessageIdInvalidRequestUrl:
                    case Constants.MessageIdMediaTypeNotSupported:
                    case Constants.MessageIdThrottledPermanently:
                    case Constants.MessageIdThrottledTemporarily:
                    case Constants.MessageIdUnauthorized:
                    case Constants.MessageIdUnknown:
                    case Constants.MessageIdUnsupportedQuery:
                    case Constants.MessageIdUnsupportedToken:
                    {
                        // We just create a new exception with the message
                        // and throw it so that the 'OnException' handler handles it
                        throw new InvalidOperationException(parsedException.Message.Value, ex);
                    }

                    // This means that the token has expired.
                    case Constants.MessageIdExpired:
                    {
                        // Renew the token and retry the operation. This is done as a
                        // part of the operation itself (AddHeaders)
                        this.AccessToken = null;
                        retryCount--;
                        break;
                    }

                    default:
                    {
                        // Not sure what happened, don't want to retry
                        throw;
                    }
                    }
                }
            }
        }