/// <summary>
        /// Obtains error messages and stack trace from an exception, including any inner exceptions contained in an AggregateException.
        /// </summary>
        /// <param name="exception">The exception to obtain the messages and stack trace from.</param>
        /// <returns>A string containing the message(s) and stack trace(s) within the exception.</returns>
        public static string GetInnerExceptionsDetail(this Exception exception)
        {
            StringBuilder sb = new StringBuilder();

            if (exception is AggregateException)
            {
                //If the exception is an aggregate exception then get the inner exceptions and flat each one of them and append them to the response
                ReadOnlyCollection <Exception> exceptions = (exception as AggregateException).Flatten().InnerExceptions;
                sb.Append("AggregateException InnerExceptions ->");

                if (exceptions != null && exceptions.Any())
                {
                    for (int i = 0; i < exceptions.Count; i++)
                    {
                        sb.AppendLine();
                        sb.Append("Exception ");
                        sb.Append(i + 1);
                        sb.AppendLine();

                        sb.Append(BaseException.FlattenInnerExceptions(exceptions[i]));
                        sb.AppendLine();
                    }
                }
                else
                {
                    sb.AppendLine("AggregateException did not contain any inner exceptions");
                }
            }
            else
            {
                //If the exception is not an aggregate one then just flat it and append it to the response
                sb.Append(BaseException.FlattenInnerExceptions(exception, "InnerExceptions ->"));
            }

            return(sb.ToString());
        }