/// <summary>
        /// Makes Rebus "legacy compatible", i.e. enables wire-level compatibility with older Rebus versions. WHen this is enabled,
        /// all endpoints need to be old Rebus endpoints or new Rebus endpoints with this feature enabled
        /// </summary>
        public static void EnableLegacyCompatibility(this OptionsConfigurer configurer)
        {
            configurer.Register<ISerializer>(c =>
            {
                var specialSettings = LegacySubscriptionMessagesBinder.JsonSerializerSettings;
                var legacyEncoding = Encoding.UTF7;
                var jsonSerializer = new JsonSerializer(specialSettings, legacyEncoding);
                return jsonSerializer;
            });

            configurer.Decorate(c =>
            {
                var pipeline = c.Get<IPipeline>();

                // map headers of incoming message from v1 to v2
                pipeline = new PipelineStepConcatenator(pipeline)
                    .OnReceive(new MapLegacyHeadersIncomingStep(), PipelineAbsolutePosition.Front);

                // unpack object[] of transport message
                pipeline = new PipelineStepInjector(pipeline)
                    .OnReceive(new UnpackLegacyMessageIncomingStep(), PipelineRelativePosition.After, typeof (DeserializeIncomingMessageStep));

                // pack into object[]
                pipeline = new PipelineStepInjector(pipeline)
                    .OnSend(new PackLegacyMessageOutgoingStep(), PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep));

                pipeline = new PipelineStepInjector(pipeline)
                    .OnSend(new MapLegacyHeadersOutgoingStep(), PipelineRelativePosition.Before, typeof(SendOutgoingMessageStep));

                //pipeline = new PipelineStepInjector(pipeline)
                //    .OnReceive(new HandleLegacySubscriptionRequestIncomingStep(c.Get<ISubscriptionStorage>(), c.Get<LegacySubscriptionMessageSerializer>()), PipelineRelativePosition.Before, typeof(MapLegacyHeadersIncomingStep));

                return pipeline;
            });

            configurer.Decorate(c =>
            {
                var transport = c.Get<ITransport>();

                if (transport is MsmqTransport)
                {
                    c.Get<IRebusLoggerFactory>()
                        .GetCurrentClassLogger()
                        .Info("MSMQ transport detected - changing to UTF7 for serialized message header encoding");

                    ((MsmqTransport) transport).UseLegacyHeaderSerialization();
                }

                return transport;
            });
        }
        /// <summary>
        /// Enables idempotent sagas. When enabled, sagas derived from <see cref="IdempotentSaga{TSagaData}"/> can be truly idempotent.
        /// This means that the saga instance stores the IDs of all handled messages, including all outgoing messages send when handling
        /// each incoming message - this way, the saga instance can guard itself against handling the same message twice, while still
        /// preserving externally visible behavior even when a message gets handled more than once.
        /// </summary>
        public static void EnableIdempotentSagas(this OptionsConfigurer configurer)
        {
            configurer.Decorate<IPipeline>(c =>
            {
                var transport = c.Get<ITransport>();
                var pipeline = c.Get<IPipeline>();

                var incomingStep = new IdempotentSagaIncomingStep(transport);

                var outgoingStep = new IdempotentSagaOutgoingStep();

                var injector = new PipelineStepInjector(pipeline)
                    .OnReceive(incomingStep, PipelineRelativePosition.Before, typeof (DispatchIncomingMessageStep))
                    .OnSend(outgoingStep, PipelineRelativePosition.After, typeof (SendOutgoingMessageStep));

                return injector;
            });
        }
        public void CanInjectStepAfterAnotherStep()
        {
            var pipeline = new DefaultPipeline()
                .OnReceive(new Step1())
                .OnReceive(new Step2())
                .OnReceive(new Step3());

            var injector = new PipelineStepInjector(pipeline)
                .OnReceive(new InjectedStep(), PipelineRelativePosition.After, typeof(Step2));

            var receivePipeline = injector.ReceivePipeline().ToArray();

            Assert.That(receivePipeline.Select(s => s.GetType()), Is.EqualTo(new[]
            {
                typeof(Step1),
                typeof(Step2),
                typeof(InjectedStep),
                typeof(Step3),
            }));
        }
        /// <summary>
        /// Makes Rebus "legacy compatible", i.e. enables wire-level compatibility with older Rebus versions. WHen this is enabled,
        /// all endpoints need to be old Rebus endpoints or new Rebus endpoints with this feature enabled
        /// </summary>
        public static void EnableLegacyCompatibility(this OptionsConfigurer configurer)
        {
            configurer.Register(c => new LegacyFlag());

            configurer.Register<ISerializer>(c =>
            {
                var specialSettings = LegacySubscriptionMessagesBinder.JsonSerializerSettings;
                var legacyEncoding = Encoding.UTF7;
                var jsonSerializer = new JsonSerializer(specialSettings, legacyEncoding);
                return jsonSerializer;
            });

            configurer.Decorate(c =>
            {
                var pipeline = c.Get<IPipeline>();

                // map headers of incoming message from v1 to v2
                pipeline = new PipelineStepConcatenator(pipeline)
                    .OnReceive(new MapLegacyHeadersIncomingStep(), PipelineAbsolutePosition.Front);

                // unpack object[] of transport message
                pipeline = new PipelineStepInjector(pipeline)
                    .OnReceive(new UnpackLegacyMessageIncomingStep(), PipelineRelativePosition.After, typeof (DeserializeIncomingMessageStep));

                // pack into object[]
                pipeline = new PipelineStepInjector(pipeline)
                    .OnSend(new PackLegacyMessageOutgoingStep(), PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep));

                pipeline = new PipelineStepInjector(pipeline)
                    .OnSend(new MapLegacyHeadersOutgoingStep(), PipelineRelativePosition.Before, typeof(SendOutgoingMessageStep));

                //pipeline = new PipelineStepInjector(pipeline)
                //    .OnReceive(new HandleLegacySubscriptionRequestIncomingStep(c.Get<ISubscriptionStorage>(), c.Get<LegacySubscriptionMessageSerializer>()), PipelineRelativePosition.Before, typeof(MapLegacyHeadersIncomingStep));

                return pipeline;
            });
        }