/// <summary>
 /// Registers multiple <see cref="IActivityMonitorClient"/>.
 /// Duplicate IActivityMonitorClient instances are ignored.
 /// </summary>
 /// <param name="this">This <see cref="IActivityMonitorOutput"/> object.</param>
 /// <param name="clients">Multiple clients to register.</param>
 /// <returns>This registrar to enable fluent syntax.</returns>
 public static IActivityMonitorOutput RegisterClients(this IActivityMonitorOutput @this, IEnumerable <IActivityMonitorClient> clients)
 {
     foreach (var c in clients)
     {
         @this.RegisterClient(c);
     }
     return(@this);
 }
 /// <summary>
 /// Removes an existing <see cref="ActivityMonitorBridge"/> to another monitor if it exists (silently ignores it if not found).
 /// </summary>
 /// <param name="this">This <see cref="IActivityMonitorOutput"/>.</param>
 /// <param name="targetBridge">The target bridge that will no more receive our logs.</param>
 /// <returns>The unregistered <see cref="ActivityMonitorBridge"/> if found, null otherwise.</returns>
 public static ActivityMonitorBridge UnbridgeTo(this IActivityMonitorOutput @this, ActivityMonitorBridgeTarget targetBridge)
 {
     if (targetBridge == null)
     {
         throw new ArgumentNullException("targetBridge");
     }
     return(UnregisterClient <ActivityMonitorBridge>(@this, b => b.BridgeTarget == targetBridge));
 }
 /// <summary>
 /// Finds an existing bridge to another monitor.
 /// </summary>
 /// <param name="this">This <see cref="IActivityMonitorOutput"/>.</param>
 /// <param name="targetBridge">The target bridge that receives our logs.</param>
 /// <returns>The existing <see cref="ActivityMonitorBridge"/> or null if no such bridge exists.</returns>
 public static ActivityMonitorBridge FindBridgeTo(this IActivityMonitorOutput @this, ActivityMonitorBridgeTarget targetBridge)
 {
     if (targetBridge == null)
     {
         throw new ArgumentNullException("targetBridge");
     }
     return(@this.Clients.OfType <ActivityMonitorBridge>().FirstOrDefault(b => b.BridgeTarget == targetBridge));
 }
        /// <summary>
        /// Unregisters the first <see cref="IActivityMonitorClient"/> from the <see cref="IActivityMonitorOutput.Clients"/> list
        /// that satisfies the predicate.
        /// </summary>
        /// <param name="this">This <see cref="IActivityMonitorOutput"/>.</param>
        /// <param name="predicate">A predicate that will be used to determine the first client to unregister.</param>
        /// <returns>The unregistered client, or null if no client has been found.</returns>
        public static T UnregisterClient <T>(this IActivityMonitorOutput @this, Func <T, bool> predicate) where T : IActivityMonitorClient
        {
            if (predicate == null)
            {
                throw new ArgumentNullException("predicate");
            }
            T c = @this.Clients.OfType <T>().Where(predicate).FirstOrDefault();

            if (c != null)
            {
                @this.UnregisterClient(c);
            }
            return(c);
        }
        /// <summary>
        /// Creates a strong bridge to another monitor's <see cref="ActivityMonitorBridgeTarget"/>.
        /// Only one bridge to the same monitor can exist at a time: if <see cref="FindBridgeTo"/> is not null,
        /// this throws a <see cref="InvalidOperationException"/>.
        /// A strong bridge synchronizes <see cref="IActivityMonitor.AutoTags"/> and <see cref="IActivityMonitor.Topic"/> between the two monitors. When created, the 2 properties
        /// of the local monitor are set to the ones of the target monitor.
        /// </summary>
        /// <param name="this">This <see cref="IActivityMonitorOutput"/>.</param>
        /// <param name="targetBridge">The target bridge that will receive our logs.</param>
        /// <returns>A <see cref="IDisposable"/> object that can be disposed to automatically call <see cref="UnbridgeTo"/>.</returns>
        public static IDisposable CreateStrongBridgeTo(this IActivityMonitorOutput @this, ActivityMonitorBridgeTarget targetBridge)
        {
            if (targetBridge == null)
            {
                throw new ArgumentNullException("targetBridge");
            }
            if (@this.Clients.OfType <ActivityMonitorBridge>().Any(b => b.BridgeTarget == targetBridge))
            {
                throw new InvalidOperationException();
            }
            var created = @this.RegisterClient(new ActivityMonitorBridge(targetBridge, true, true));

            return(Util.CreateDisposableAction(() => @this.UnregisterClient(created)));
        }
 /// <summary>
 /// Registers a unique client for a type that must have a public default constructor.
 /// <see cref="Activator.CreateInstance{T}()"/> is called if necessary.
 /// </summary>
 /// <returns>The found or newly created client.</returns>
 public static T RegisterUniqueClient <T>(this IActivityMonitorOutput @this)
     where T : IActivityMonitorClient, new()
 {
     return(@this.RegisterUniqueClient(c => true, () => Activator.CreateInstance <T>()));
 }
 /// <summary>
 /// Registers multiple <see cref="IActivityMonitorClient"/>.
 /// Duplicate IActivityMonitorClient instances are ignored.
 /// </summary>
 /// <param name="this">This <see cref="IActivityMonitorOutput"/> object.</param>
 /// <param name="clients">Multiple clients to register.</param>
 /// <returns>This registrar to enable fluent syntax.</returns>
 public static IActivityMonitorOutput RegisterClients(this IActivityMonitorOutput @this, params IActivityMonitorClient[] clients)
 {
     return(RegisterClients(@this, (IEnumerable <IActivityMonitorClient>)clients));
 }
        /// <summary>
        /// Registers a typed <see cref="IActivityMonitorClient"/>.
        /// Duplicate IActivityMonitorClient instances are ignored.
        /// </summary>
        /// <typeparam name="T">Any type that specializes <see cref="IActivityMonitorClient"/>.</typeparam>
        /// <param name="this">This <see cref="IActivityMonitorOutput"/> object.</param>
        /// <param name="client">Client to register.</param>
        /// <returns>The registered client.</returns>
        public static T RegisterClient <T>(this IActivityMonitorOutput @this, T client) where T : IActivityMonitorClient
        {
            bool added;

            return(@this.RegisterClient <T>(client, out added));
        }
        /// <summary>
        /// Registers an <see cref="IActivityMonitorClient"/> to the <see cref="IActivityMonitorOutput.Clients">Clients</see> list.
        /// Duplicates IActivityMonitorClient are silently ignored.
        /// </summary>
        /// <param name="this">This <see cref="IActivityMonitorOutput"/> object.</param>
        /// <param name="client">An <see cref="IActivityMonitorClient"/> implementation.</param>
        /// <returns>The registered client.</returns>
        public static IActivityMonitorClient RegisterClient(this IActivityMonitorOutput @this, IActivityMonitorClient client)
        {
            bool added;

            return(@this.RegisterClient(client, out added));
        }