/// <summary>
        /// Replaces the default <see cref="IWebRequestCreate"/> for "http://" and
        /// "https:// urls with a custom <see cref="IWebRequestCreate"/>, such as
        /// <see cref="HttpWebRequestWrapperInterceptorCreator"/> or <see cref="HttpWebRequestWrapperRecorderCreator"/>.
        /// This will also hook into new <see cref="WebClient"/>s and <see cref="HttpClient"/>s!
        /// <para />
        /// After creating a <see cref="HttpWebRequestWrapperSession"/>, any code that uses
        /// <see cref="WebRequest.Create(System.Uri)"/>, new <see cref="WebClient"/>() or
        /// new <see cref="HttpClient"/>() will receive a custom <see cref="HttpWebRequest"/>
        /// built by the passed <see cref="IWebRequestCreate"/>.
        /// <para />
        /// This works by both hijacking <see cref="M:WebRequest.PrefixList"/>
        /// and using <see cref="TaskSchedulerProxy"/> and
        /// <see cref="HttpClientHandlerStartRequestTaskVisitor"/> to intercept
        /// <see cref="System.Net.Http.HttpClient"/> before it begins processing a
        /// <see cref="HttpWebRequest"/> / <see cref="HttpRequestMessage"/>
        /// <para />
        /// NOTE: This technique is only able to support <see cref="System.Net.Http.HttpClient"/>
        /// that are using a <see cref="HttpMessageHandler"/> that derives from
        /// <see cref="HttpClientHandler"/>.  If you are using a purely custom
        /// <see cref="HttpMessageHandler"/>, this class will not intercept
        /// http requests, you'd need to change how your <see cref="System.Net.Http.HttpClient"/>s
        /// are built to fallback to using the default <see cref="HttpClientHandler"/> for
        /// test runs.
        /// <para />
        /// Calling <see cref="Dispose"/> will reset reset the <see cref="M:WebRequest.PrefixList"/>
        /// and the <see cref="TaskScheduler.Default"/>; restoring default behavior.
        /// <para />
        /// See <see cref="HttpWebRequestWrapperSession"/> for more information on
        /// how the <see cref="IWebRequestCreate"/> process is intercepted.
        /// <para />
        /// NOTE: This class does not support concurrency.  It relies on manipulating a static field
        /// (<see cref="TaskScheduler.Default"/> and <see cref="M:WebRequest.PrefixList"/>).
        /// You can only create one Session at a time for a given
        /// App Domain. However, you can run concurrent code within the Session.
        /// </summary>
        public HttpWebRequestWrapperSession(IWebRequestCreate httpRequestCreator)
        {
            _originalWebRequestPrefixList = WebRequestReflectionExtensions.GetWebRequestPrefixList();

            WebRequest.RegisterPrefix("http://", httpRequestCreator);
            WebRequest.RegisterPrefix("https://", httpRequestCreator);

            _defaultTaskScheduler = TaskScheduler.Current;

            // replace the default TaskScheduler.Default with a custom
            // proxy that's wired up with the HttpClientHandlerStartRequestTaskVisitor
            var httpClientInterceptorTaskScheduler =
                new TaskSchedulerProxy(
                    new IVisitTaskOnSchedulerQueue[]
            {
                new HttpClientHandlerStartRequestTaskVisitor.DotNet45AndEarlierStrategy(),
                new HttpClientHandlerStartRequestTaskVisitor.DotNet47Strategy()
            },
                    TaskScheduler.Current);

            httpClientInterceptorTaskScheduler.SetAsDefaultTaskScheduler();
        }
        /// <summary>
        /// Restores the original <see cref="TaskScheduler.Current"/>
        /// as well as the work done in <see cref="HttpWebRequestWrapperSession.Dispose"/>
        /// </summary>
        public virtual void Dispose()
        {
            WebRequestReflectionExtensions.SetWebRequestPrefixList(_originalWebRequestPrefixList);

            _defaultTaskScheduler.SetAsDefaultTaskScheduler();
        }