/// <summary>
		/// Create a work item queue that will try to pull items from a named RabbitMQ endpoint
		/// </summary>
		/// <param name="endpoint">Destination endpoint to pull messages from</param>
		/// <param name="messagingBase">RabbitMQ connection provider</param>
		/// <param name="sleeper">Sleeper to rate limit polling</param>
		public RabbitMqPollingNode(IRoutingEndpoint endpoint,
			IMessagingBase messagingBase, ISleepWrapper sleeper)
		{
			_endpoint = endpoint.ToString();
			_messagingBase = messagingBase;
			_sleeper = sleeper;
			_boundMessageTypes = new ConcurrentSet<Type>();
		}
		/// <summary>
		/// Create a default local queue polling node factory
		/// <para>You should not use this yourself. Use:</para>
		/// <para>MessagingSystem.Configure.WithLocalQueue(...);</para>
		/// </summary>
		public LocalQueuePollingNodeFactory(LocalQueueConfig config,
		                                    IMessageSerialiser serialiser, ISleepWrapper sleeper)
		{
			_serialiser = serialiser;
			_sleeper = sleeper;
			_dispatchPath = config.DispatchPath;
			_incomingPath = config.IncomingPath;
		}
		/// <summary>
		/// Create a local polling node.
		/// <para>You should not use this yourself. Use:</para>
		/// <para>MessagingSystem.Configure.WithLocalQueue(...);</para>
		/// and receive messages as normal.
		/// </summary>
		public LocalQueuePollingNode(string dispatchPath, string incomingPath,
		                             IMessageSerialiser serialiser, ISleepWrapper sleeper)
		{
			_dispatchPath = dispatchPath;
			_incomingPath = incomingPath;
			_serialiser = serialiser;
			_sleeper = sleeper;
			_boundMessageTypes = new ConcurrentSet<Type>();
		}
		public void setup()
		{
			_endpoint = Substitute.For<IRoutingEndpoint>();
			_messagingBase = Substitute.For<IMessagingBase>();
			_sleepWrapper = Substitute.For<ISleepWrapper>();

			_endpoint.ToString().Returns(_destinationName);

			_subject = new RabbitMqPollingNode(_endpoint, _messagingBase, _sleepWrapper);
		}
		public void setup()
		{
			_messagingBase = Substitute.For<IMessagingBase>();
			_sleeper = Substitute.For<ISleepWrapper>();
			_dispatcher = Substitute.For<IDispatch<byte[]>>();
			_dispatcherFactory = Substitute.For<IDispatcherFactory>();
			_dispatcherFactory.Create(Arg.Any<IWorkQueue<byte[]>>(), Arg.Any<IWorkerPool<byte[]>>()).Returns(_dispatcher);

			_queueFactory = Substitute.For<IOutgoingQueueFactory>();

			_eventHook1 = Substitute.For<IEventHook>();
			_eventHook2 = Substitute.For<IEventHook>();
			ObjectFactory.Configure(map => {
				map.For<IEventHook>().Use(_eventHook1);
				map.For<IEventHook>().Use(_eventHook2);
			});

			_subject = new SenderNode(_messagingBase, _dispatcherFactory, _sleeper,_queueFactory);
		}
		public void setup()
		{
			_subject = new SleepWrapper();
		}
		readonly Dictionary<Type, ISet<Type>> _handlers; // message type => [handler types]

		/// <summary>
		/// New dispatcher
		/// </summary>
		public HandlerManager(ISleepWrapper sleeper)
		{
			_sleeper = sleeper;
			_handlers = new Dictionary<Type, ISet<Type>>();
		}
		/// <summary>
		/// Generate a polling node factory for RabbitMq
		/// </summary>
		public RabbitMqPollingNodeFactory(IMessagingBase messagingBase, ISleepWrapper sleeper)
		{
			_messagingBase = messagingBase;
			_sleeper = sleeper;
		}