private void track(final Module module, MessageChannel channel, final Map<String, Object> historyProps) {
		final MessageBuilderFactory messageBuilderFactory = module.getComponent(
				IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME,
				MessageBuilderFactory.class) == null
				? new DefaultMessageBuilderFactory()
				: module.getComponent(
						IntegrationUtils.INTEGRATION_MESSAGE_BUILDER_FACTORY_BEAN_NAME,
						MessageBuilderFactory.class);
		if (channel instanceof ChannelInterceptorAware) {
			((ChannelInterceptorAware) channel).addInterceptor(new ChannelInterceptorAdapter() {

				@Override
				public Message<?> preSend(Message<?> message, MessageChannel channel) {
					@SuppressWarnings("unchecked")
					Collection<Map<String, Object>> history =
							(Collection<Map<String, Object>>) message.getHeaders().get(XdHeaders.XD_HISTORY);
					if (history == null) {
						history = new ArrayList<Map<String, Object>>(1);
					}
					else {
						history = new ArrayList<Map<String, Object>>(history);
					}
					Map<String, Object> map = new LinkedHashMap<String, Object>();
					map.putAll(historyProps);
					map.put("thread", Thread.currentThread().getName());
					history.add(map);
					Message<?> out = messageBuilderFactory
							.fromMessage(message)
							.setHeader(XdHeaders.XD_HISTORY, history)
							.build();
					map.put("timestamp", out.getHeaders().getTimestamp());
					return out;
				}
			});
		}
	}
Bind input/output channel of the module's message consumer/producers to {@link MessageBus}'s message
source/target entities. The producer must be bound first so that messages can immediately
start flowing from the consumer.

@param module the module whose consumer and producers to bind to the {@link MessageBus}.
spring-xd-dirt/src/main/java/org/springframework/xd/dirt/plugins/AbstractMessageBusBinderPlugin.java