/// <summary>
        /// Converts to.
        /// </summary>
        /// <param name="sqlException">The SQL exception.</param>
        /// <returns>Beyova.Diagnostic.BaseException.</returns>
        public static BaseException ConvertTo(SqlStoredProcedureException sqlException)
        {
            BaseException result = null;

            if (sqlException != null)
            {
                switch (sqlException.Code.Major)
                {
                case ExceptionCode.MajorCode.NullOrInvalidValue:
                    result = new InvalidObjectException(sqlException, reason: sqlException.Code.Minor);
                    break;

                case ExceptionCode.MajorCode.UnauthorizedOperation:
                    result = new UnauthorizedOperationException(sqlException, minorCode: sqlException.Code.Minor);
                    break;

                case ExceptionCode.MajorCode.OperationForbidden:
                    result = new OperationForbiddenException(sqlException.Code.Minor, sqlException);
                    break;

                case ExceptionCode.MajorCode.DataConflict:
                    result = new DataConflictException(sqlException.Code.Minor, innerException: sqlException);
                    break;

                default:
                    result = sqlException;
                    break;
                }
            }

            return(result);
        }
        /// <summary>
        /// Validates the API permission.
        /// </summary>
        /// <param name="userPermissions">The user permissions.</param>
        /// <param name="methodPermissions">The method permissions.</param>
        /// <param name="token">The token.</param>
        /// <param name="methodName">Name of the method.</param>
        /// <returns>BaseException.</returns>
        public static BaseException ValidateApiPermission(this ICollection <string> userPermissions, IDictionary <string, ApiPermissionAttribute> methodPermissions, string token, string methodName)
        {
            const string defaultMinor = "ApiPermissionConstraint";

            BaseException result = null;
            var           permissionValidationResult = userPermissions.ValidateApiPermission(methodPermissions);

            if (permissionValidationResult != null)
            {
                var data = new
                {
                    userPermissions,
                    methodPermissions,
                    result = new
                    {
                        permissionIdentifier = permissionValidationResult.PermissionIdentifier,
                        apiPermission        = permissionValidationResult.DeclaredApiPermissionRule.Permission
                    }
                };

                if (permissionValidationResult.DeclaredApiPermissionRule?.ExceptionBehavior != null)
                {
                    var reason = permissionValidationResult.DeclaredApiPermissionRule.ExceptionBehavior.Minor.SafeToString(defaultMinor);

                    switch (permissionValidationResult.DeclaredApiPermissionRule.ExceptionBehavior.Major)
                    {
                    case ExceptionCode.MajorCode.UnauthorizedOperation:
                        result = new UnauthorizedOperationException(reason, data: data);
                        break;

                    case ExceptionCode.MajorCode.OperationForbidden:
                        result = new OperationForbiddenException(reason, data: data);
                        break;

                    default:
                        break;
                    }
                }

                if (result == null)
                {
                    result = new UnauthorizedOperationException(minorCode: defaultMinor, data: data);
                }
            }

            return(result);
        }
        /// <summary>
        /// Handles the exception.
        /// </summary>
        /// <param name="exception">The exception.</param>
        /// <param name="operationIdentity">The operation identity.</param>
        /// <param name="operatorIdentity">The operator identity.</param>
        /// <param name="data">The data.</param>
        /// <returns>BaseServiceException.</returns>
        public BaseServiceException HandleException(BaseException exception, string operationIdentity, string operatorIdentity = null, object data = null)
        {
            if (exception != null)
            {
                BaseException baseException = null;

                if (exception.ErrorCode == BaseException.FaultCode.UnauthorizedOperation)
                {
                    baseException = new UnauthorizedOperationException(operationIdentity.GetStringValue(), operatorIdentity.GetStringValue(), exception, data);
                }
                else
                {
                    baseException = new OperationFailureException(operationIdentity, exception, data);
                }

                Logger.LogException(baseException);
                return(baseException.ToServiceException());
            }
            else
            {
                return(new UnknownServiceException());
            }
        }
        /// <summary>
        /// To the exception.
        /// </summary>
        /// <param name="exceptionInfo">The exception information.</param>
        /// <returns>System.Exception.</returns>
        public static Exception ToException(this ExceptionInfo exceptionInfo)
        {
            Exception result = null;

            if (exceptionInfo != null)
            {
                var innerException = exceptionInfo.InnerException;

                switch (exceptionInfo.ExceptionType)
                {
                case "Beyova.Diagnostic.HttpOperationException":
                    return(new HttpOperationException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint));

                case "Beyova.Diagnostic.SqlStoredProcedureException":
                    return(new SqlStoredProcedureException(exceptionInfo.Message, exceptionInfo.Code));

                default:
                    break;
                }

                switch (exceptionInfo.Code.Major)
                {
                case ExceptionCode.MajorCode.CreditNotAfford:
                    result = new CreditNotAffordException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.DataConflict:
                    result = new DataConflictException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.NotImplemented:
                    result = new UnimplementedException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.NullOrInvalidValue:
                    result = new InvalidObjectException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.OperationFailure:
                    result = new OperationFailureException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.OperationForbidden:
                    result = new OperationForbiddenException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.ResourceNotFound:
                    result = new ResourceNotFoundException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.ServiceUnavailable:
                    result = new ServiceUnavailableException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.UnauthorizedOperation:
                    result = new UnauthorizedOperationException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.HttpBlockError:
                    result = new HttpOperationException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                case ExceptionCode.MajorCode.Unsupported:
                    result = new UnsupportedException(exceptionInfo.Key ?? Guid.NewGuid(), exceptionInfo.CreatedStamp ?? DateTime.UtcNow, exceptionInfo.Message, exceptionInfo.Scene, exceptionInfo.Code, ToException(innerException), exceptionInfo.OperatorCredential, exceptionInfo.Data, exceptionInfo.Hint);
                    break;

                default:
                    result = new Exception(exceptionInfo.Message);
                    break;
                }
            }

            return(result);
        }