class SpringRabbitTracing {

  public RabbitTemplate decorateRabbitTemplate(RabbitTemplate rabbitTemplate) {
    // Skip out if we can't read the field for the existing post processors
    if (beforePublishPostProcessorsField == null) return rabbitTemplate;
    Collection<MessagePostProcessor> processors;
    try {
      processors = (Collection) beforePublishPostProcessorsField.get(rabbitTemplate);
    } catch (IllegalAccessException e) {
      return rabbitTemplate;
    }

    TracingMessagePostProcessor tracingMessagePostProcessor = new TracingMessagePostProcessor(this);
    // If there are no existing post processors, return only the tracing one
    if (processors == null) {
      rabbitTemplate.setBeforePublishPostProcessors(tracingMessagePostProcessor);
      return rabbitTemplate;
    }

    // If there is an existing tracing post processor return
    for (MessagePostProcessor processor : processors) {
      if (processor instanceof TracingMessagePostProcessor) {
        return rabbitTemplate;
      }
    }

    // Otherwise, add ours and return
    List<MessagePostProcessor> newProcessors = new ArrayList<>(processors.size() + 1);
    newProcessors.addAll(processors);
    newProcessors.add(tracingMessagePostProcessor);
    rabbitTemplate.setBeforePublishPostProcessors(
      newProcessors.toArray(new MessagePostProcessor[0])
    );
    return rabbitTemplate;
  }

    SpringRabbitTracing(Builder builder);

}