public async Task StartServer(CancellationToken token = default(CancellationToken))
        {
            // Get any available handlers
            var handlers = new List <HandlerRegistration>();

            Type[] handlerTypes = _handlerFactory.GetAllHandlerTypes();
            foreach (Type handlerType in handlerTypes)
            {
                // Try to get the IHandleMessage<T> interface from the handlerType
                var handlerInterfaces = handlerType.IsMessageHandlerInterface()
                                            ? new Type[] { handlerType }                           // The handlerType itself is already IHandleMessage<T>
                                            : handlerType.GetMessageHandlerInterfaces().ToArray(); // The handlerType should implement IHandleMessage<T> at least once

                if (handlerInterfaces.Length == 0)
                {
                    throw new InvalidOperationException($"The handler Type {handlerType.Name} is not a message handler");
                }

                // Get the message Type T from IHandleMessage<T> and create a handler registration by invoking the static factory method
                // on HandlerRegistration with the appropriate type arguments
                foreach (Type handlerInterface in handlerInterfaces)
                {
                    Type messageType = handlerInterface.GenericTypeArguments.Single();
                    var  handler     =
                        (HandlerRegistration)HandlerRegistrationFactoryMethod.MakeGenericMethod(handlerType, messageType).Invoke(this, null);
                    handlers.Add(handler);
                }
            }

            // Nothing to do if no handlers
            if (handlers.Count == 0)
            {
                return;
            }

            // Get the unique message FullNames amongst the handlers and use those as the topic name to subscribe to
            Dictionary <string, List <HandlerRegistration> > handlersByTopic = handlers.GroupBy(h => h.MessageDescriptor.FullName)
                                                                               .ToDictionary(g => g.Key, g => g.ToList());

            // Subscribe to all topics
            Subscription[] subscriptions = await Task.WhenAll(handlersByTopic.Select(kvp => Subscribe(kvp.Key, kvp.Value, token)))
                                           .ConfigureAwait(false);

            // Kick off a background task to pull messages off the transport for each subscription and dispatch the messages
            _runningServer = Task.Run(() => RunServer(subscriptions, _cancelRunningServer.Token), _cancelRunningServer.Token);
        }