/// <summary>
        /// Discovers tests in the application and maps routes to allow them to be called over HTTP.
        /// </summary>
        /// <param name="configuration">The configuration.</param>
        /// <param name="configureTargets">A delegate to configure the test targets.</param>
        /// <param name="baseUri">The base URI segment that the tests will be routed under.</param>
        /// <param name="testTypes">The Types to map routes for. If omitted, all discovered implementations of <see cref="IMonitoringTest" /> will be routed.</param>
        /// <param name="handler">A message handler to handle test requests, if you would like to provide authentication, logging, or other functionality during calls to monitoring tests.</param>
        /// <param name="testUiScriptUrl">The location of the test UI script.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">configuration</exception>
        public static HttpConfiguration MapTestRoutes(
            this HttpConfiguration configuration,
            Action <TestTargetRegistry> configureTargets = null,
            string baseUri = "tests",
            IEnumerable <Type> testTypes = null,
            HttpMessageHandler handler   = null,
            string testUiScriptUrl       = null)
        {
            if (configuration == null)
            {
                throw new ArgumentNullException("configuration");
            }

            if (!Trace.Listeners.OfType <TracingFilter.TraceListener>().Any())
            {
                var traceListener = new TracingFilter.TraceListener();
                Trace.Listeners.Add(traceListener);
                Instrumentation.Log.EntryPosted += (_, args) => traceListener.WriteLine(args.LogEntry.ToLogString());
            }

            // set up specialized handling on the specified routes
            configuration.Filters.Add(new TestErrorFilter(baseUri));
            if (!string.IsNullOrEmpty(testUiScriptUrl) && Uri.IsWellFormedUriString(testUiScriptUrl, UriKind.RelativeOrAbsolute))
            {
                configuration.TestUiUriIs(testUiScriptUrl);
            }

            var testRootRouteTemplate = baseUri.AppendSegment("{environment}/{application}");

            configuration.RootTestUriIs(baseUri);

            // set up test discovery routes
            configuration.Routes.MapHttpRoute(
                TestRootRouteName,
                testRootRouteTemplate,
                defaults: new
            {
                controller  = "MonitoringTest",
                action      = "tests",
                application = RouteParameter.Optional,
                environment = RouteParameter.Optional
            },
                constraints: null,
                handler: handler);

            // set up test execution routes
            var targetRegistry = new TestTargetRegistry(configuration);

            configuration.TestTargetsAre(targetRegistry);
            if (configureTargets != null)
            {
                configureTargets(targetRegistry);
            }

            testTypes = testTypes ?? Discover.ConcreteTypes()
                        .DerivedFrom(typeof(IMonitoringTest));

            var testDefinitions = testTypes.GetTestDefinitions();

            configuration.TestDefinitionsAre(testDefinitions);

            testDefinitions.Select(p => p.Value)
            .ForEach(test =>
            {
                var targetConstraint = new TargetConstraint(test);

                targetRegistry.ForEach(target =>
                {
                    Task.Run(() => targetConstraint.Match(target));
                });

                configuration.Routes.MapHttpRoute(
                    test.RouteName,
                    testRootRouteTemplate.AppendSegment(test.TestName),
                    defaults: new
                {
                    controller = "MonitoringTest",
                    action     = "run",
                    testName   = test.TestName
                },
                    constraints: new
                {
                    tag         = new TagConstraint(test),
                    application = new ApplicationConstraint(test),
                    environment = new EnvironmentConstraint(test),
                    target      = targetConstraint
                },
                    handler: handler
                    );
            });

            return(configuration);
        }
 internal static void TestTargetsAre(this HttpConfiguration configuration,
                                     TestTargetRegistry targets)
 {
     configuration.Properties["Its.Log.Monitoring.TestTargets"] = targets;
 }