diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..bdf2dcb
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,5 @@
+/Tests export-ignore
+.gitattributes export-ignore
+.gitignore export-ignore
+.travis.yml export-ignore
+phpunit.xml.dist export-ignore
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..0492424
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,29 @@
+name: CI
+on:
+  pull_request:
+  push:
+    branches:
+      - master
+jobs:
+  tests:
+    runs-on: ubuntu-latest
+    strategy:
+      fail-fast: false
+      matrix:
+        php: ['7.4', '8.0', '8.1', '8.2']
+
+    name: PHP ${{ matrix.php }} tests
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - uses: shivammathur/setup-php@v2
+        with:
+          php-version: ${{ matrix.php }}
+          coverage: none
+
+      - uses: "ramsey/composer-install@v1"
+        with:
+          composer-options: "--prefer-source"
+
+      - run: vendor/bin/phpunit --exclude-group=functional
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b9cf57f..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-sudo: false
-
-git:
-    depth: 10
-
-language: php
-
-php:
-    - '5.6'
-    - '7.0'
-
-cache:
-    directories:
-        - $HOME/.composer/cache
-
-install:
-    - composer self-update
-    - composer install --prefer-source
-
-script:
-    - vendor/bin/phpunit --exclude-group=functional
diff --git a/AbstractAsyncEventDispatcher.php b/AbstractAsyncEventDispatcher.php
new file mode 100644
index 0000000..5bc7d27
--- /dev/null
+++ b/AbstractAsyncEventDispatcher.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Enqueue\AsyncEventDispatcher;
+
+use Symfony\Component\EventDispatcher\Event;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Contracts\EventDispatcher\Event as ContractEvent;
+
+abstract class AbstractAsyncEventDispatcher extends EventDispatcher implements EventDispatcherInterface
+{
+    /**
+     * @var EventDispatcherInterface
+     */
+    protected $trueEventDispatcher;
+
+    /**
+     * @var AsyncListener
+     */
+    protected $asyncListener;
+
+    public function __construct(EventDispatcherInterface $trueEventDispatcher, AsyncListener $asyncListener)
+    {
+        $this->trueEventDispatcher = $trueEventDispatcher;
+        $this->asyncListener = $asyncListener;
+    }
+
+    /**
+     * This method dispatches only those listeners that were marked as async.
+     *
+     * @param string                   $eventName
+     * @param ContractEvent|Event|null $event
+     */
+    public function dispatchAsyncListenersOnly($eventName, $event = null)
+    {
+        try {
+            $this->asyncListener->syncMode($eventName);
+
+            $this->parentDispatch($event, $eventName);
+        } finally {
+            $this->asyncListener->resetSyncMode();
+        }
+    }
+
+    abstract protected function parentDispatch($event, $eventName);
+}
diff --git a/AbstractAsyncListener.php b/AbstractAsyncListener.php
new file mode 100644
index 0000000..d4ac19a
--- /dev/null
+++ b/AbstractAsyncListener.php
@@ -0,0 +1,62 @@
+<?php
+
+namespace Enqueue\AsyncEventDispatcher;
+
+use Interop\Queue\Context;
+use Interop\Queue\Queue;
+
+abstract class AbstractAsyncListener
+{
+    /**
+     * @var Context
+     */
+    protected $context;
+
+    /**
+     * @var Registry
+     */
+    protected $registry;
+
+    /**
+     * @var Queue
+     */
+    protected $eventQueue;
+
+    /**
+     * @var bool
+     */
+    protected $syncMode;
+
+    /**
+     * @param Queue|string $eventQueue
+     */
+    public function __construct(Context $context, Registry $registry, $eventQueue)
+    {
+        $this->context = $context;
+        $this->registry = $registry;
+        $this->eventQueue = $eventQueue instanceof Queue ? $eventQueue : $context->createQueue($eventQueue);
+    }
+
+    public function resetSyncMode()
+    {
+        $this->syncMode = [];
+    }
+
+    /**
+     * @param string $eventName
+     */
+    public function syncMode($eventName)
+    {
+        $this->syncMode[$eventName] = true;
+    }
+
+    /**
+     * @param string $eventName
+     *
+     * @return bool
+     */
+    public function isSyncMode($eventName)
+    {
+        return isset($this->syncMode[$eventName]);
+    }
+}
diff --git a/AbstractPhpSerializerEventTransformer.php b/AbstractPhpSerializerEventTransformer.php
new file mode 100644
index 0000000..6ac53cb
--- /dev/null
+++ b/AbstractPhpSerializerEventTransformer.php
@@ -0,0 +1,24 @@
+<?php
+
+namespace Enqueue\AsyncEventDispatcher;
+
+use Interop\Queue\Context;
+use Interop\Queue\Message;
+
+abstract class AbstractPhpSerializerEventTransformer
+{
+    /**
+     * @var Context
+     */
+    protected $context;
+
+    public function __construct(Context $context)
+    {
+        $this->context = $context;
+    }
+
+    public function toEvent($eventName, Message $message)
+    {
+        return unserialize($message->getBody());
+    }
+}
diff --git a/AsyncEventDispatcher.php b/AsyncEventDispatcher.php
index c74d974..e39136e 100644
--- a/AsyncEventDispatcher.php
+++ b/AsyncEventDispatcher.php
@@ -2,56 +2,17 @@
 
 namespace Enqueue\AsyncEventDispatcher;
 
-use Symfony\Component\EventDispatcher\Event;
-use Symfony\Component\EventDispatcher\EventDispatcher;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-
-class AsyncEventDispatcher extends EventDispatcher
+class AsyncEventDispatcher extends AbstractAsyncEventDispatcher
 {
-    /**
-     * @var EventDispatcherInterface
-     */
-    private $trueEventDispatcher;
-
-    /**
-     * @var AsyncListener
-     */
-    private $asyncListener;
-
-    /**
-     * @param EventDispatcherInterface $trueEventDispatcher
-     * @param AsyncListener            $asyncListener
-     */
-    public function __construct(EventDispatcherInterface $trueEventDispatcher, AsyncListener $asyncListener)
+    public function dispatch(object $event, ?string $eventName = null): object
     {
-        $this->trueEventDispatcher = $trueEventDispatcher;
-        $this->asyncListener = $asyncListener;
-    }
+        $this->parentDispatch($event, $eventName);
 
-    /**
-     * This method dispatches only those listeners that were marked as async.
-     *
-     * @param string     $eventName
-     * @param Event|null $event
-     */
-    public function dispatchAsyncListenersOnly($eventName, Event $event = null)
-    {
-        try {
-            $this->asyncListener->syncMode($eventName);
-
-            parent::dispatch($eventName, $event);
-        } finally {
-            $this->asyncListener->resetSyncMode();
-        }
+        return $this->trueEventDispatcher->dispatch($event, $eventName);
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    public function dispatch($eventName, Event $event = null)
+    protected function parentDispatch($event, $eventName)
     {
-        parent::dispatch($eventName, $event);
-
-        $this->trueEventDispatcher->dispatch($eventName, $event);
+        return parent::dispatch($event, $eventName);
     }
 }
diff --git a/AsyncListener.php b/AsyncListener.php
index 524fdb2..2be4976 100644
--- a/AsyncListener.php
+++ b/AsyncListener.php
@@ -2,74 +2,16 @@
 
 namespace Enqueue\AsyncEventDispatcher;
 
-use Interop\Queue\PsrContext;
-use Interop\Queue\PsrQueue;
-use Symfony\Component\EventDispatcher\Event;
+use Symfony\Contracts\EventDispatcher\Event;
 
-class AsyncListener
+class AsyncListener extends AbstractAsyncListener
 {
-    /**
-     * @var PsrContext
-     */
-    private $context;
-
-    /**
-     * @var Registry
-     */
-    private $registry;
-
-    /**
-     * @var PsrQueue
-     */
-    private $eventQueue;
-
-    /**
-     * @var bool
-     */
-    private $syncMode;
-
-    /**
-     * @param PsrContext      $context
-     * @param Registry        $registry
-     * @param PsrQueue|string $eventQueue
-     */
-    public function __construct(PsrContext $context, Registry $registry, $eventQueue)
-    {
-        $this->context = $context;
-        $this->registry = $registry;
-        $this->eventQueue = $eventQueue instanceof PsrQueue ? $eventQueue : $context->createQueue($eventQueue);
-    }
-
     public function __invoke(Event $event, $eventName)
     {
         $this->onEvent($event, $eventName);
     }
 
-    public function resetSyncMode()
-    {
-        $this->syncMode = [];
-    }
-
-    /**
-     * @param string $eventName
-     */
-    public function syncMode($eventName)
-    {
-        $this->syncMode[$eventName] = true;
-    }
-
-    /**
-     * @param string $eventName
-     *
-     * @return bool
-     */
-    public function isSyncMode($eventName)
-    {
-        return isset($this->syncMode[$eventName]);
-    }
-
     /**
-     * @param Event  $event
      * @param string $eventName
      */
     public function onEvent(Event $event, $eventName)
diff --git a/AsyncProcessor.php b/AsyncProcessor.php
index a472d76..dc61c53 100644
--- a/AsyncProcessor.php
+++ b/AsyncProcessor.php
@@ -3,12 +3,12 @@
 namespace Enqueue\AsyncEventDispatcher;
 
 use Enqueue\Consumption\Result;
-use Interop\Queue\PsrContext;
-use Interop\Queue\PsrMessage;
-use Interop\Queue\PsrProcessor;
+use Interop\Queue\Context;
+use Interop\Queue\Message;
+use Interop\Queue\Processor;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
-class AsyncProcessor implements PsrProcessor
+class AsyncProcessor implements Processor
 {
     /**
      * @var Registry
@@ -16,34 +16,22 @@ class AsyncProcessor implements PsrProcessor
     private $registry;
 
     /**
-     * @var AsyncEventDispatcher|OldAsyncEventDispatcher
+     * @var AsyncEventDispatcher
      */
     private $dispatcher;
 
-    /**
-     * @param Registry                 $registry
-     * @param EventDispatcherInterface $dispatcher
-     */
     public function __construct(Registry $registry, EventDispatcherInterface $dispatcher)
     {
         $this->registry = $registry;
 
-        if (false == ($dispatcher instanceof AsyncEventDispatcher || $dispatcher instanceof OldAsyncEventDispatcher)) {
-            throw new \InvalidArgumentException(sprintf(
-                'The dispatcher argument must be either instance of "%s" or "%s" but got "%s"',
-                AsyncEventDispatcher::class,
-                OldAsyncEventDispatcher::class,
-                get_class($dispatcher)
-            ));
+        if (false == $dispatcher instanceof AsyncEventDispatcher) {
+            throw new \InvalidArgumentException(sprintf('The dispatcher argument must be instance of "%s" but got "%s"', AsyncEventDispatcher::class, $dispatcher::class));
         }
 
         $this->dispatcher = $dispatcher;
     }
 
-    /**
-     * {@inheritdoc}
-     */
-    public function process(PsrMessage $message, PsrContext $context)
+    public function process(Message $message, Context $context)
     {
         if (false == $eventName = $message->getProperty('event_name')) {
             return Result::reject('The message is missing "event_name" property');
diff --git a/Commands.php b/Commands.php
new file mode 100644
index 0000000..c2263ee
--- /dev/null
+++ b/Commands.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Enqueue\AsyncEventDispatcher;
+
+final class Commands
+{
+    public const DISPATCH_ASYNC_EVENTS = 'symfony.dispatch_async_events';
+}
diff --git a/ContainerAwareRegistry.php b/ContainerAwareRegistry.php
index 2763ed7..b0e23f2 100644
--- a/ContainerAwareRegistry.php
+++ b/ContainerAwareRegistry.php
@@ -2,12 +2,14 @@
 
 namespace Enqueue\AsyncEventDispatcher;
 
-use Symfony\Component\DependencyInjection\ContainerAwareInterface;
-use Symfony\Component\DependencyInjection\ContainerAwareTrait;
+use Psr\Container\ContainerInterface;
 
-class ContainerAwareRegistry implements Registry, ContainerAwareInterface
+class ContainerAwareRegistry implements Registry
 {
-    use ContainerAwareTrait;
+    /**
+     * @var ContainerInterface
+     */
+    private $container;
 
     /**
      * @var string[]
@@ -23,15 +25,13 @@ class ContainerAwareRegistry implements Registry, ContainerAwareInterface
      * @param string[] $eventsMap       [eventName => transformerName]
      * @param string[] $transformersMap [transformerName => transformerServiceId]
      */
-    public function __construct(array $eventsMap, array $transformersMap)
+    public function __construct(array $eventsMap, array $transformersMap, ContainerInterface $container)
     {
         $this->eventsMap = $eventsMap;
         $this->transformersMap = $transformersMap;
+        $this->container = $container;
     }
 
-    /**
-     * {@inheritdoc}
-     */
     public function getTransformerNameForEvent($eventName)
     {
         $transformerName = null;
@@ -39,7 +39,7 @@ public function getTransformerNameForEvent($eventName)
             $transformerName = $this->eventsMap[$eventName];
         } else {
             foreach ($this->eventsMap as $eventNamePattern => $name) {
-                if ('/' != $eventNamePattern[0]) {
+                if ('/' !== $eventNamePattern[0]) {
                     continue;
                 }
 
@@ -58,9 +58,6 @@ public function getTransformerNameForEvent($eventName)
         return $transformerName;
     }
 
-    /**
-     * {@inheritdoc}
-     */
     public function getTransformer($name)
     {
         if (false == array_key_exists($name, $this->transformersMap)) {
@@ -69,12 +66,8 @@ public function getTransformer($name)
 
         $transformer = $this->container->get($this->transformersMap[$name]);
 
-        if (false == $transformer instanceof  EventTransformer) {
-            throw new \LogicException(sprintf(
-                'The container must return instance of %s but got %s',
-                EventTransformer::class,
-                is_object($transformer) ? get_class($transformer) : gettype($transformer)
-            ));
+        if (false == $transformer instanceof EventTransformer) {
+            throw new \LogicException(sprintf('The container must return instance of %s but got %s', EventTransformer::class, is_object($transformer) ? $transformer::class : gettype($transformer)));
         }
 
         return $transformer;
diff --git a/DependencyInjection/AsyncEventDispatcherExtension.php b/DependencyInjection/AsyncEventDispatcherExtension.php
index 160999d..0b16ca6 100644
--- a/DependencyInjection/AsyncEventDispatcherExtension.php
+++ b/DependencyInjection/AsyncEventDispatcherExtension.php
@@ -2,35 +2,36 @@
 
 namespace Enqueue\AsyncEventDispatcher\DependencyInjection;
 
-use Enqueue\AsyncEventDispatcher\OldAsyncEventDispatcher;
+use Enqueue\AsyncEventDispatcher\AsyncProcessor;
+use Enqueue\AsyncEventDispatcher\Commands;
 use Symfony\Component\Config\FileLocator;
+use Symfony\Component\DependencyInjection\Alias;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\DependencyInjection\Definition;
 use Symfony\Component\DependencyInjection\Extension\Extension;
 use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
 use Symfony\Component\DependencyInjection\Reference;
-use Symfony\Component\HttpKernel\Kernel;
 
 class AsyncEventDispatcherExtension extends Extension
 {
-    /**
-     * {@inheritdoc}
-     */
     public function load(array $configs, ContainerBuilder $container)
     {
         $config = $this->processConfiguration(new Configuration(), $configs);
 
-        $container->setAlias('enqueue.events.context', $config['context_service']);
+        $container->setAlias('enqueue.events.context', new Alias($config['context_service'], true));
 
         $loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
         $loader->load('services.yml');
 
-        if (version_compare(Kernel::VERSION, '3.3', '<')) {
-            $container->setDefinition('enqueue.events.event_dispatcher', new Definition(OldAsyncEventDispatcher::class, [
-                new Reference('service_container'),
-                new Reference('event_dispatcher'),
-                new Reference('enqueue.events.async_listener'),
-            ]));
-        }
+        $container->register('enqueue.events.async_processor', AsyncProcessor::class)
+            ->addArgument(new Reference('enqueue.events.registry'))
+            ->addArgument(new Reference('enqueue.events.event_dispatcher'))
+            ->addTag('enqueue.processor', [
+                'command' => Commands::DISPATCH_ASYNC_EVENTS,
+                'queue' => '%enqueue_events_queue%',
+                'prefix_queue' => false,
+                'exclusive' => true,
+            ])
+            ->addTag('enqueue.transport.processor')
+        ;
     }
 }
diff --git a/DependencyInjection/AsyncEventsPass.php b/DependencyInjection/AsyncEventsPass.php
index 1db8035..42774ad 100644
--- a/DependencyInjection/AsyncEventsPass.php
+++ b/DependencyInjection/AsyncEventsPass.php
@@ -4,15 +4,11 @@
 
 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
 use Symfony\Component\DependencyInjection\ContainerBuilder;
-use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
 
 class AsyncEventsPass implements CompilerPassInterface
 {
-    /**
-     * {@inheritdoc}
-     */
-    public function process(ContainerBuilder $container)
+    public function process(ContainerBuilder $container): void
     {
         if (false == $container->hasDefinition('enqueue.events.async_listener')) {
             return;
@@ -22,6 +18,8 @@ public function process(ContainerBuilder $container)
             return;
         }
 
+        $defaultClient = $container->getParameter('enqueue.default_client');
+
         $registeredToEvent = [];
         foreach ($container->findTaggedServiceIds('kernel.event_listener') as $serviceId => $tagAttributes) {
             foreach ($tagAttributes as $tagAttribute) {
@@ -31,11 +29,6 @@ public function process(ContainerBuilder $container)
 
                 $event = $tagAttribute['event'];
 
-                $service = $container->getDefinition($serviceId);
-
-                $service->clearTag('kernel.event_listener');
-                $service->addTag('enqueue.async_event_listener', $tagAttribute);
-
                 if (false == isset($registeredToEvent[$event])) {
                     $container->getDefinition('enqueue.events.async_listener')
                         ->addTag('kernel.event_listener', [
@@ -44,9 +37,18 @@ public function process(ContainerBuilder $container)
                         ])
                     ;
 
+                    $container->getDefinition('enqueue.events.async_listener')
+                        ->addTag('kernel.event_listener', [
+                            'event' => $event,
+                            'method' => 'onEvent',
+                            'dispatcher' => 'enqueue.events.event_dispatcher',
+                        ])
+                    ;
+
                     $container->getDefinition('enqueue.events.async_processor')
-                        ->addTag('enqueue.client.processor', [
-                            'topicName' => 'event.'.$event,
+                        ->addTag('enqueue.processor', [
+                            'topic' => 'event.'.$event,
+                            'client' => $defaultClient,
                         ])
                     ;
 
@@ -62,8 +64,6 @@ public function process(ContainerBuilder $container)
                 }
 
                 $service = $container->getDefinition($serviceId);
-                $service->clearTag('kernel.event_subscriber');
-                $service->addTag('enqueue.async_event_subscriber', $tagAttribute);
 
                 /** @var EventSubscriberInterface $serviceClass */
                 $serviceClass = $service->getClass();
@@ -77,9 +77,18 @@ public function process(ContainerBuilder $container)
                             ])
                         ;
 
+                        $container->getDefinition('enqueue.events.async_listener')
+                            ->addTag('kernel.event_listener', [
+                                'event' => $event,
+                                'method' => 'onEvent',
+                                'dispatcher' => 'enqueue.events.event_dispatcher',
+                            ])
+                        ;
+
                         $container->getDefinition('enqueue.events.async_processor')
-                            ->addTag('enqueue.client.processor', [
+                            ->addTag('enqueue.processor', [
                                 'topicName' => 'event.'.$event,
+                                'client' => $defaultClient,
                             ])
                         ;
 
@@ -88,12 +97,5 @@ public function process(ContainerBuilder $container)
                 }
             }
         }
-
-        $registerListenersPass = new RegisterListenersPass(
-            'enqueue.events.event_dispatcher',
-            'enqueue.async_event_listener',
-            'enqueue.async_event_subscriber'
-        );
-        $registerListenersPass->process($container);
     }
 }
diff --git a/DependencyInjection/AsyncTransformersPass.php b/DependencyInjection/AsyncTransformersPass.php
index 0adcfcb..89046dd 100644
--- a/DependencyInjection/AsyncTransformersPass.php
+++ b/DependencyInjection/AsyncTransformersPass.php
@@ -7,9 +7,6 @@
 
 class AsyncTransformersPass implements CompilerPassInterface
 {
-    /**
-     * {@inheritdoc}
-     */
     public function process(ContainerBuilder $container)
     {
         if (false == $container->hasDefinition('enqueue.events.registry')) {
@@ -18,6 +15,7 @@ public function process(ContainerBuilder $container)
 
         $transformerIdsMap = [];
         $eventNamesMap = [];
+        $defaultTransformer = null;
         foreach ($container->findTaggedServiceIds('enqueue.event_transformer') as $serviceId => $tagAttributes) {
             foreach ($tagAttributes as $tagAttribute) {
                 if (false == isset($tagAttribute['eventName'])) {
@@ -28,11 +26,24 @@ public function process(ContainerBuilder $container)
 
                 $transformerName = isset($tagAttribute['transformerName']) ? $tagAttribute['transformerName'] : $serviceId;
 
-                $eventNamesMap[$eventName] = $transformerName;
-                $transformerIdsMap[$transformerName] = $serviceId;
+                if (isset($tagAttribute['default']) && $tagAttribute['default']) {
+                    $defaultTransformer = [
+                        'id' => $serviceId,
+                        'transformerName' => $transformerName,
+                        'eventName' => $eventName,
+                    ];
+                } else {
+                    $eventNamesMap[$eventName] = $transformerName;
+                    $transformerIdsMap[$transformerName] = $serviceId;
+                }
             }
         }
 
+        if ($defaultTransformer) {
+            $eventNamesMap[$defaultTransformer['eventName']] = $defaultTransformer['transformerName'];
+            $transformerIdsMap[$defaultTransformer['transformerName']] = $defaultTransformer['id'];
+        }
+
         $container->getDefinition('enqueue.events.registry')
             ->replaceArgument(0, $eventNamesMap)
             ->replaceArgument(1, $transformerIdsMap)
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index 9703e62..7b85a46 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -7,13 +7,15 @@
 
 class Configuration implements ConfigurationInterface
 {
-    /**
-     * {@inheritdoc}
-     */
-    public function getConfigTreeBuilder()
+    public function getConfigTreeBuilder(): TreeBuilder
     {
-        $tb = new TreeBuilder();
-        $rootNode = $tb->root('enqueue_async_event_dispatcher');
+        if (method_exists(TreeBuilder::class, 'getRootNode')) {
+            $tb = new TreeBuilder('enqueue_async_event_dispatcher');
+            $rootNode = $tb->getRootNode();
+        } else {
+            $tb = new TreeBuilder();
+            $rootNode = $tb->root('enqueue_async_event_dispatcher');
+        }
 
         $rootNode->children()
             ->scalarNode('context_service')->isRequired()->cannotBeEmpty()->end()
diff --git a/EventTransformer.php b/EventTransformer.php
index 4aa2360..271dffa 100644
--- a/EventTransformer.php
+++ b/EventTransformer.php
@@ -2,28 +2,26 @@
 
 namespace Enqueue\AsyncEventDispatcher;
 
-use Interop\Queue\PsrMessage;
-use Symfony\Component\EventDispatcher\Event;
+use Interop\Queue\Message;
+use Symfony\Contracts\EventDispatcher\Event;
 
 interface EventTransformer
 {
     /**
-     * @param string     $eventName
-     * @param Event|null $event
+     * @param string $eventName
      *
-     * @return PsrMessage
+     * @return Message
      */
-    public function toMessage($eventName, Event $event);
+    public function toMessage($eventName, ?Event $event = null);
 
     /**
      * If you able to transform message back to event return it.
-     * If you failed to transform for some reason you can return a string status (@see PsrProcess constants) or an object that implements __toString method.
-     * The object must have a __toString method is supposed to be used as PsrProcessor::process return value.
-     *
-     * @param string     $eventName
-     * @param PsrMessage $message
+     * If you failed to transform for some reason you can return a string status.
      *
      * @return Event|string|object
+     *
+     * @see Process constants) or an object that implements __toString method.
+     *      The object must have a __toString method is supposed to be used as Processor::process return value.
      */
-    public function toEvent($eventName, PsrMessage $message);
+    public function toEvent($eventName, Message $message);
 }
diff --git a/OldAsyncEventDispatcher.php b/OldAsyncEventDispatcher.php
deleted file mode 100644
index 97720af..0000000
--- a/OldAsyncEventDispatcher.php
+++ /dev/null
@@ -1,61 +0,0 @@
-<?php
-
-namespace Enqueue\AsyncEventDispatcher;
-
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
-use Symfony\Component\EventDispatcher\Event;
-use Symfony\Component\EventDispatcher\EventDispatcherInterface;
-
-class OldAsyncEventDispatcher extends ContainerAwareEventDispatcher
-{
-    /**
-     * @var EventDispatcherInterface
-     */
-    private $trueEventDispatcher;
-
-    /**
-     * @var AsyncListener
-     */
-    private $asyncListener;
-
-    /**
-     * @param ContainerInterface       $container
-     * @param EventDispatcherInterface $trueEventDispatcher
-     * @param AsyncListener            $asyncListener
-     */
-    public function __construct(ContainerInterface $container, EventDispatcherInterface $trueEventDispatcher, AsyncListener $asyncListener)
-    {
-        parent::__construct($container);
-
-        $this->trueEventDispatcher = $trueEventDispatcher;
-        $this->asyncListener = $asyncListener;
-    }
-
-    /**
-     * This method dispatches only those listeners that were marked as async.
-     *
-     * @param string     $eventName
-     * @param Event|null $event
-     */
-    public function dispatchAsyncListenersOnly($eventName, Event $event = null)
-    {
-        try {
-            $this->asyncListener->syncMode($eventName);
-
-            parent::dispatch($eventName, $event);
-        } finally {
-            $this->asyncListener->resetSyncMode();
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function dispatch($eventName, Event $event = null)
-    {
-        parent::dispatch($eventName, $event);
-
-        $this->trueEventDispatcher->dispatch($eventName, $event);
-    }
-}
diff --git a/PhpSerializerEventTransformer.php b/PhpSerializerEventTransformer.php
index d99d0d4..9c23883 100644
--- a/PhpSerializerEventTransformer.php
+++ b/PhpSerializerEventTransformer.php
@@ -2,66 +2,12 @@
 
 namespace Enqueue\AsyncEventDispatcher;
 
-use Interop\Queue\PsrContext;
-use Interop\Queue\PsrMessage;
-use Symfony\Component\EventDispatcher\Event;
-use Symfony\Component\HttpKernel\Kernel;
+use Symfony\Contracts\EventDispatcher\Event;
 
-class PhpSerializerEventTransformer implements EventTransformer
+class PhpSerializerEventTransformer extends AbstractPhpSerializerEventTransformer implements EventTransformer
 {
-    /**
-     * @var PsrContext
-     */
-    private $context;
-
-    /**
-     * @var bool
-     */
-    private $skipSymfonyVersionCheck;
-
-    /**
-     * @param PsrContext $context
-     * @param bool       $skipSymfonyVersionCheck It is useful when async dispatcher is used without Kernel. So there is no way to check the version.
-     */
-    public function __construct(PsrContext $context, $skipSymfonyVersionCheck = false)
+    public function toMessage($eventName, ?Event $event = null)
     {
-        $this->context = $context;
-        $this->skipSymfonyVersionCheck = $skipSymfonyVersionCheck;
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function toMessage($eventName, Event $event = null)
-    {
-        $this->assertSymfony30OrHigher();
-
         return $this->context->createMessage(serialize($event));
     }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function toEvent($eventName, PsrMessage $message)
-    {
-        $this->assertSymfony30OrHigher();
-
-        return unserialize($message->getBody());
-    }
-
-    private function assertSymfony30OrHigher()
-    {
-        if ($this->skipSymfonyVersionCheck) {
-            return;
-        }
-
-        if (version_compare(Kernel::VERSION, '3.0', '<')) {
-            throw new \LogicException(
-                'This transformer does not work on Symfony prior 3.0. '.
-                'The event contains eventDispatcher and therefor could not be serialized. '.
-                'You have to register a transformer for every async event. '.
-                'Read the doc: https://github.com/php-enqueue/enqueue-dev/blob/master/docs/bundle/async_events.md#event-transformer'
-            );
-        }
-    }
 }
diff --git a/README.md b/README.md
index 3df85a5..c4804d9 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,33 @@
+<h2 align="center">Supporting Enqueue</h2>
+
+Enqueue is an MIT-licensed open source project with its ongoing development made possible entirely by the support of community and our customers. If you'd like to join them, please consider:
+
+- [Become a sponsor](https://www.patreon.com/makasim)
+- [Become our client](http://forma-pro.com/)
+
+---
+
 # Symfony Async Event Dispatcher.
 
 [![Gitter](https://badges.gitter.im/php-enqueue/Lobby.svg)](https://gitter.im/php-enqueue/Lobby)
-[![Build Status](https://travis-ci.org/php-enqueue/async-event-dispathcer.png?branch=master)](https://travis-ci.org/php-enqueue/async-event-dispathcer)
-[![Total Downloads](https://poser.pugx.org/enqueue/async-event-dispathcer/d/total.png)](https://packagist.org/packages/enqueue/async-event-dispathcer)
-[![Latest Stable Version](https://poser.pugx.org/enqueue/async-event-dispathcer/version.png)](https://packagist.org/packages/enqueue/async-event-dispathcer)
- 
-It contains an extension to Symfony's [EventDispatcher](https://symfony.com/doc/current/components/event_dispatcher.html) component. 
-It allows to processes events in background by sending them to MQ.  
+[![Build Status](https://img.shields.io/github/actions/workflow/status/php-enqueue/async-event-dispatcher/ci.yml?branch=master)](https://github.com/php-enqueue/async-event-dispathcer/actions?query=workflow%3ACI)
+[![Total Downloads](https://poser.pugx.org/enqueue/async-event-dispathcer/d/total.png)](https://packagist.org/packages/enqueue/async-event-dispatcher)
+[![Latest Stable Version](https://poser.pugx.org/enqueue/async-event-dispathcer/version.png)](https://packagist.org/packages/enqueue/async-event-dispatcher)
+
+It contains an extension to Symfony's [EventDispatcher](https://symfony.com/doc/current/components/event_dispatcher.html) component.
+It allows to process events in background by sending them to MQ.
 
 ## Resources
 
-* [Documentation](https://github.com/php-enqueue/enqueue-dev/blob/master/docs/index.md)
+* [Site](https://enqueue.forma-pro.com/)
+* [Documentation](https://php-enqueue.github.io/)
 * [Questions](https://gitter.im/php-enqueue/Lobby)
 * [Issue Tracker](https://github.com/php-enqueue/enqueue-dev/issues)
 
 ## Developed by Forma-Pro
 
-Forma-Pro is a full stack development company which interests also spread to open source development. 
-Being a team of strong professionals we have an aim an ability to help community by developing cutting edge solutions in the areas of e-commerce, docker & microservice oriented architecture where we have accumulated a huge many-years experience. 
+Forma-Pro is a full stack development company which interests also spread to open source development.
+Being a team of strong professionals we have an aim an ability to help community by developing cutting edge solutions in the areas of e-commerce, docker & microservice oriented architecture where we have accumulated a huge many-years experience.
 Our main specialization is Symfony framework based solution, but we are always looking to the technologies that allow us to do our job the best way. We are committed to creating solutions that revolutionize the way how things are developed in aspects of architecture & scalability.
 
 If you have any questions and inquires about our open source development, this product particularly or any other matter feel free to contact at opensource@forma-pro.com
diff --git a/Resources/config/services.yml b/Resources/config/services.yml
index 94dd698..67365dc 100644
--- a/Resources/config/services.yml
+++ b/Resources/config/services.yml
@@ -8,38 +8,25 @@ services:
     enqueue.events.registry:
         class: 'Enqueue\AsyncEventDispatcher\ContainerAwareRegistry'
         public: false
-        arguments: [[], []]
-        calls:
-            -  ['setContainer', ['@service_container']]
+        arguments: [[], [], '@service_container']
 
     enqueue.events.async_listener:
         class: 'Enqueue\AsyncEventDispatcher\AsyncListener'
+        public: public
         arguments: ['@enqueue.events.context', '@enqueue.events.registry', '%enqueue_events_queue%']
 
 
     enqueue.events.event_dispatcher:
         class: 'Enqueue\AsyncEventDispatcher\AsyncEventDispatcher'
+        public: public
         arguments:
             - '@event_dispatcher'
             - '@enqueue.events.async_listener'
 
-    enqueue.events.async_processor:
-        class: 'Enqueue\AsyncEventDispatcher\AsyncProcessor'
-        arguments:
-            - '@enqueue.events.registry'
-            - '@enqueue.events.event_dispatcher'
-        tags:
-            -
-                name: 'enqueue.client.processor'
-                topicName: '__command__'
-                processorName: '%enqueue_events_queue%'
-                queueName: '%enqueue_events_queue%'
-                queueNameHardcoded: true
-                exclusive: true
-
-    enqueue.events.php_serializer_event_transofrmer:
+    enqueue.events.php_serializer_event_transformer:
         class: 'Enqueue\AsyncEventDispatcher\PhpSerializerEventTransformer'
+        public: public
         arguments:
             - '@enqueue.events.context'
         tags:
-            - {name: 'enqueue.event_transformer', eventName: '/.*/', transformerName: 'php_serializer' }
+            - {name: 'enqueue.event_transformer', eventName: '/.*/', transformerName: 'php_serializer', default: true }
diff --git a/SimpleRegistry.php b/SimpleRegistry.php
index 2f39d0c..e5ba16e 100644
--- a/SimpleRegistry.php
+++ b/SimpleRegistry.php
@@ -24,9 +24,6 @@ public function __construct(array $eventsMap, array $transformersMap)
         $this->transformersMap = $transformersMap;
     }
 
-    /**
-     * {@inheritdoc}
-     */
     public function getTransformerNameForEvent($eventName)
     {
         $transformerName = null;
@@ -53,9 +50,6 @@ public function getTransformerNameForEvent($eventName)
         return $transformerName;
     }
 
-    /**
-     * {@inheritdoc}
-     */
     public function getTransformer($name)
     {
         if (false == array_key_exists($name, $this->transformersMap)) {
@@ -64,12 +58,8 @@ public function getTransformer($name)
 
         $transformer = $this->transformersMap[$name];
 
-        if (false == $transformer instanceof  EventTransformer) {
-            throw new \LogicException(sprintf(
-                'The container must return instance of %s but got %s',
-                EventTransformer::class,
-                is_object($transformer) ? get_class($transformer) : gettype($transformer)
-            ));
+        if (false == $transformer instanceof EventTransformer) {
+            throw new \LogicException(sprintf('The container must return instance of %s but got %s', EventTransformer::class, is_object($transformer) ? $transformer::class : gettype($transformer)));
         }
 
         return $transformer;
diff --git a/Tests/AsyncListenerTest.php b/Tests/AsyncListenerTest.php
index c3e6c0a..d888c02 100644
--- a/Tests/AsyncListenerTest.php
+++ b/Tests/AsyncListenerTest.php
@@ -8,15 +8,18 @@
 use Enqueue\Null\NullMessage;
 use Enqueue\Null\NullQueue;
 use Enqueue\Test\ClassExtensionTrait;
-use Interop\Queue\PsrContext;
-use Interop\Queue\PsrProducer;
+use Enqueue\Test\ReadAttributeTrait;
+use Interop\Queue\Context;
+use Interop\Queue\Producer;
+use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
-use Symfony\Component\EventDispatcher\Event;
 use Symfony\Component\EventDispatcher\GenericEvent;
+use Symfony\Contracts\EventDispatcher\Event;
 
 class AsyncListenerTest extends TestCase
 {
     use ClassExtensionTrait;
+    use ReadAttributeTrait;
 
     public function testCouldBeConstructedWithContextAndRegistryAndEventQueueAsString()
     {
@@ -35,7 +38,7 @@ public function testCouldBeConstructedWithContextAndRegistryAndEventQueueAsStrin
         $this->assertAttributeSame($eventQueue, 'eventQueue', $listener);
     }
 
-    public function testCouldBeConstructedWithContextAndRegistryAndPsrQueue()
+    public function testCouldBeConstructedWithContextAndRegistryAndQueue()
     {
         $eventQueue = new NullQueue('symfony_events');
 
@@ -129,7 +132,7 @@ public function testShouldSendMessageIfSyncModeOff()
     }
 
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|EventTransformer
+     * @return MockObject|EventTransformer
      */
     private function createEventTransformerMock()
     {
@@ -137,23 +140,23 @@ private function createEventTransformerMock()
     }
 
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|PsrProducer
+     * @return MockObject|Producer
      */
     private function createProducerMock()
     {
-        return $this->createMock(PsrProducer::class);
+        return $this->createMock(Producer::class);
     }
 
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|PsrContext
+     * @return MockObject|Context
      */
     private function createContextMock()
     {
-        return $this->createMock(PsrContext::class);
+        return $this->createMock(Context::class);
     }
 
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|Registry
+     * @return MockObject|Registry
      */
     private function createRegistryMock()
     {
diff --git a/Tests/AsyncProcessorTest.php b/Tests/AsyncProcessorTest.php
index 9502908..019f9bc 100644
--- a/Tests/AsyncProcessorTest.php
+++ b/Tests/AsyncProcessorTest.php
@@ -10,7 +10,8 @@
 use Enqueue\Null\NullContext;
 use Enqueue\Null\NullMessage;
 use Enqueue\Test\ClassExtensionTrait;
-use Interop\Queue\PsrProcessor;
+use Interop\Queue\Processor;
+use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
 use Symfony\Component\EventDispatcher\GenericEvent;
 
@@ -20,12 +21,7 @@ class AsyncProcessorTest extends TestCase
 
     public function testShouldImplementProcessorInterface()
     {
-        $this->assertClassImplements(PsrProcessor::class, AsyncProcessor::class);
-    }
-
-    public function testCouldBeConstructedWithRegistryAndProxyEventDispatcher()
-    {
-        new AsyncProcessor($this->createRegistryMock(), $this->createProxyEventDispatcherMock());
+        $this->assertClassImplements(Processor::class, AsyncProcessor::class);
     }
 
     public function testRejectIfMessageMissingEventNameProperty()
@@ -97,7 +93,7 @@ public function testShouldDispatchAsyncListenersOnly()
     }
 
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|EventTransformer
+     * @return MockObject|EventTransformer
      */
     private function createEventTransformerMock()
     {
@@ -105,7 +101,7 @@ private function createEventTransformerMock()
     }
 
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|AsyncEventDispatcher
+     * @return MockObject|AsyncEventDispatcher
      */
     private function createProxyEventDispatcherMock()
     {
@@ -113,7 +109,7 @@ private function createProxyEventDispatcherMock()
     }
 
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|Registry
+     * @return MockObject|Registry
      */
     private function createRegistryMock()
     {
diff --git a/Tests/ContainerAwareRegistryTest.php b/Tests/ContainerAwareRegistryTest.php
index 1255502..79762ac 100644
--- a/Tests/ContainerAwareRegistryTest.php
+++ b/Tests/ContainerAwareRegistryTest.php
@@ -6,49 +6,39 @@
 use Enqueue\AsyncEventDispatcher\EventTransformer;
 use Enqueue\AsyncEventDispatcher\Registry;
 use Enqueue\Test\ClassExtensionTrait;
+use Enqueue\Test\ReadAttributeTrait;
 use PHPUnit\Framework\TestCase;
 use Symfony\Component\DependencyInjection\Container;
 
 class ContainerAwareRegistryTest extends TestCase
 {
     use ClassExtensionTrait;
+    use ReadAttributeTrait;
 
     public function testShouldImplementRegistryInterface()
     {
         $this->assertClassImplements(Registry::class, ContainerAwareRegistry::class);
     }
 
-    public function testCouldBeConstructedWithEventsMapAndTransformersMapAsArguments()
-    {
-        new ContainerAwareRegistry([], []);
-    }
-
-    public function testShouldSetContainerToContainerProperty()
+    public function testShouldAllowGetTransportNameByEventName()
     {
         $container = new Container();
 
-        $registry = new ContainerAwareRegistry([], []);
-
-        $registry->setContainer($container);
-
-        $this->assertAttributeSame($container, 'container', $registry);
-    }
-
-    public function testShouldAllowGetTransportNameByEventName()
-    {
         $registry = new ContainerAwareRegistry([
-                'fooEvent' => 'fooTrans',
-        ], []);
+            'fooEvent' => 'fooTrans',
+        ], [], $container);
 
         $this->assertEquals('fooTrans', $registry->getTransformerNameForEvent('fooEvent'));
     }
 
     public function testShouldAllowDefineTransportNameAsRegExpPattern()
     {
+        $container = new Container();
+
         $registry = new ContainerAwareRegistry([
             '/.*/' => 'fooRegExpTrans',
             'fooEvent' => 'fooTrans',
-        ], []);
+        ], [], $container);
 
         // guard
         $this->assertEquals('fooTrans', $registry->getTransformerNameForEvent('fooEvent'));
@@ -58,9 +48,11 @@ public function testShouldAllowDefineTransportNameAsRegExpPattern()
 
     public function testThrowIfNotSupportedEventGiven()
     {
+        $container = new Container();
+
         $registry = new ContainerAwareRegistry([
             'fooEvent' => 'fooTrans',
-        ], []);
+        ], [], $container);
 
         $this->expectException(\LogicException::class);
         $this->expectExceptionMessage('There is no transformer registered for the given event fooNotSupportedEvent');
@@ -69,9 +61,11 @@ public function testThrowIfNotSupportedEventGiven()
 
     public function testThrowIfThereIsNoRegisteredTransformerWithSuchName()
     {
+        $container = new Container();
+
         $registry = new ContainerAwareRegistry([], [
             'fooTrans' => 'foo_trans_id',
-        ]);
+        ], $container);
 
         $this->expectException(\LogicException::class);
         $this->expectExceptionMessage('There is no transformer named fooNotRegisteredName');
@@ -85,8 +79,7 @@ public function testThrowIfContainerReturnsServiceNotInstanceOfEventTransformer(
 
         $registry = new ContainerAwareRegistry([], [
             'fooTrans' => 'foo_trans_id',
-        ]);
-        $registry->setContainer($container);
+        ], $container);
 
         $this->expectException(\LogicException::class);
         $this->expectExceptionMessage('The container must return instance of Enqueue\AsyncEventDispatcher\EventTransformer but got stdClass');
@@ -102,8 +95,7 @@ public function testShouldReturnEventTransformer()
 
         $registry = new ContainerAwareRegistry([], [
             'fooTrans' => 'foo_trans_id',
-        ]);
-        $registry->setContainer($container);
+        ], $container);
 
         $this->assertSame($eventTransformerMock, $registry->getTransformer('fooTrans'));
     }
diff --git a/Tests/Functional/UseCasesTest.php b/Tests/Functional/UseCasesTest.php
index 1c2768d..169d8ea 100644
--- a/Tests/Functional/UseCasesTest.php
+++ b/Tests/Functional/UseCasesTest.php
@@ -8,9 +8,9 @@
 use Enqueue\AsyncEventDispatcher\SimpleRegistry;
 use Enqueue\Bundle\Tests\Functional\App\TestAsyncEventTransformer;
 use Enqueue\Fs\FsConnectionFactory;
-use Interop\Queue\PsrContext;
-use Interop\Queue\PsrProcessor;
-use Interop\Queue\PsrQueue;
+use Interop\Queue\Context;
+use Interop\Queue\Processor;
+use Interop\Queue\Queue;
 use PHPUnit\Framework\TestCase;
 use Symfony\Component\EventDispatcher\Event;
 use Symfony\Component\EventDispatcher\EventDispatcher;
@@ -24,12 +24,12 @@
 class UseCasesTest extends TestCase
 {
     /**
-     * @var PsrContext
+     * @var Context
      */
     protected $context;
 
     /**
-     * @var PsrQueue
+     * @var Queue
      */
     protected $queue;
 
@@ -53,7 +53,7 @@ class UseCasesTest extends TestCase
      */
     protected $asyncProcessor;
 
-    public function setUp()
+    protected function setUp(): void
     {
         (new Filesystem())->remove(__DIR__.'/queues/');
 
@@ -104,7 +104,7 @@ public function testShouldDispatchBothAsyncEventAndSyncOne()
             echo "Async event\n";
         });
 
-        $this->dispatcher->dispatch('test_async', new GenericEvent());
+        $this->dispatch($this->dispatcher, new GenericEvent(), 'test_async');
         $this->processMessages();
 
         $this->expectOutputString("Sync event\nSend message for event: test_async\nAsync event\n");
@@ -115,7 +115,7 @@ public function testShouldDispatchBothAsyncEventAndSyncOneFromWhenDispatchedFrom
         $this->dispatcher->addListener('foo', function ($event, $name, EventDispatcherInterface $dispatcher) {
             echo "Foo event\n";
 
-            $dispatcher->dispatch('test_async', new GenericEvent());
+            $this->dispatch($dispatcher, new GenericEvent(), 'test_async');
         });
 
         $this->dispatcher->addListener('test_async', function () {
@@ -128,7 +128,8 @@ public function testShouldDispatchBothAsyncEventAndSyncOneFromWhenDispatchedFrom
             echo "Async event\n";
         });
 
-        $this->dispatcher->dispatch('foo');
+        $this->dispatch($this->dispatcher, new GenericEvent(), 'foo');
+
         $this->processMessages();
 
         $this->expectOutputString("Foo event\nSync event\nSend message for event: test_async\nAsync event\n");
@@ -142,14 +143,14 @@ public function testShouldDispatchOtherAsyncEventFromAsyncEvent()
         $this->asyncDispatcher->addListener('test_async', function ($event, $eventName, EventDispatcherInterface $dispatcher) {
             echo "Async event\n";
 
-            $dispatcher->dispatch('test_async_from_async');
+            $this->dispatch($dispatcher, new GenericEvent(), 'test_async_from_async');
         });
 
         $this->dispatcher->addListener('test_async_from_async', function ($event, $eventName, EventDispatcherInterface $dispatcher) {
             echo "Async event from event\n";
         });
 
-        $this->dispatcher->dispatch('test_async');
+        $this->dispatch($this->dispatcher, new GenericEvent(), 'test_async');
 
         $this->processMessages();
         $this->processMessages();
@@ -168,16 +169,27 @@ public function testShouldDispatchSyncListenerIfDispatchedFromAsycListner()
         $this->asyncDispatcher->addListener('test_async', function ($event, $eventName, EventDispatcherInterface $dispatcher) {
             echo "Async event\n";
 
-            $dispatcher->dispatch('sync');
+            $this->dispatch($dispatcher, new GenericEvent(), 'sync');
         });
 
-        $this->dispatcher->dispatch('test_async');
+        $this->dispatch($this->dispatcher, new GenericEvent(), 'test_async');
 
         $this->processMessages();
 
         $this->expectOutputString("Send message for event: test_async\nAsync event\nSync event\n");
     }
 
+    private function dispatch(EventDispatcherInterface $dispatcher, $event, $eventName): void
+    {
+        if (!class_exists(Event::class)) {
+            // Symfony 5
+            $dispatcher->dispatch($event, $eventName);
+        } else {
+            // Symfony < 5
+            $dispatcher->dispatch($eventName, $event);
+        }
+    }
+
     private function processMessages()
     {
         $consumer = $this->context->createConsumer($this->queue);
@@ -185,13 +197,13 @@ private function processMessages()
             $result = $this->asyncProcessor->process($message, $this->context);
 
             switch ((string) $result) {
-                case PsrProcessor::ACK:
+                case Processor::ACK:
                     $consumer->acknowledge($message);
                     break;
-                case PsrProcessor::REJECT:
+                case Processor::REJECT:
                     $consumer->reject($message);
                     break;
-                case PsrProcessor::REQUEUE:
+                case Processor::REQUEUE:
                     $consumer->reject($message, true);
                     break;
                 default:
diff --git a/Tests/PhpSerializerEventTransformerTest.php b/Tests/PhpSerializerEventTransformerTest.php
index 407b44c..498ca3a 100644
--- a/Tests/PhpSerializerEventTransformerTest.php
+++ b/Tests/PhpSerializerEventTransformerTest.php
@@ -6,11 +6,11 @@
 use Enqueue\AsyncEventDispatcher\PhpSerializerEventTransformer;
 use Enqueue\Null\NullMessage;
 use Enqueue\Test\ClassExtensionTrait;
-use Interop\Queue\PsrContext;
-use Interop\Queue\PsrMessage;
+use Interop\Queue\Context;
+use Interop\Queue\Message;
+use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
 use Symfony\Component\EventDispatcher\GenericEvent;
-use Symfony\Component\HttpKernel\Kernel;
 
 class PhpSerializerEventTransformerTest extends TestCase
 {
@@ -21,17 +21,8 @@ public function testShouldImplementEventTransformerInterface()
         $this->assertClassImplements(EventTransformer::class, PhpSerializerEventTransformer::class);
     }
 
-    public function testCouldBeConstructedWithoutAnyArguments()
-    {
-        new PhpSerializerEventTransformer($this->createContextStub());
-    }
-
     public function testShouldReturnMessageWithPhpSerializedEventAsBodyOnToMessage()
     {
-        if (version_compare(Kernel::VERSION, '3.0', '<')) {
-            $this->markTestSkipped('This functionality only works on Symfony 3.0 or higher');
-        }
-
         $transformer = new PhpSerializerEventTransformer($this->createContextStub());
 
         $event = new GenericEvent('theSubject');
@@ -39,16 +30,12 @@ public function testShouldReturnMessageWithPhpSerializedEventAsBodyOnToMessage()
 
         $message = $transformer->toMessage('fooEvent', $event);
 
-        $this->assertInstanceOf(PsrMessage::class, $message);
+        $this->assertInstanceOf(Message::class, $message);
         $this->assertEquals($expectedBody, $message->getBody());
     }
 
     public function testShouldReturnEventUnserializedFromMessageBodyOnToEvent()
     {
-        if (version_compare(Kernel::VERSION, '3.0', '<')) {
-            $this->markTestSkipped('This functionality only works on Symfony 3.0 or higher');
-        }
-
         $message = new NullMessage();
         $message->setBody(serialize(new GenericEvent('theSubject')));
 
@@ -60,40 +47,12 @@ public function testShouldReturnEventUnserializedFromMessageBodyOnToEvent()
         $this->assertEquals('theSubject', $event->getSubject());
     }
 
-    public function testThrowNotSupportedExceptionOnSymfonyPrior30OnToMessage()
-    {
-        if (version_compare(Kernel::VERSION, '3.0', '>=')) {
-            $this->markTestSkipped('This functionality only works on Symfony 3.0 or higher');
-        }
-
-        $this->expectException(\LogicException::class);
-        $this->expectExceptionMessage('This transformer does not work on Symfony prior 3.0.');
-
-        $transformer = new PhpSerializerEventTransformer($this->createContextStub());
-
-        $transformer->toMessage(new GenericEvent());
-    }
-
-    public function testThrowNotSupportedExceptionOnSymfonyPrior30OnToEvent()
-    {
-        if (version_compare(Kernel::VERSION, '3.0', '>=')) {
-            $this->markTestSkipped('This functionality only works on Symfony 3.0 or higher');
-        }
-
-        $this->expectException(\LogicException::class);
-        $this->expectExceptionMessage('This transformer does not work on Symfony prior 3.0.');
-
-        $transformer = new PhpSerializerEventTransformer($this->createContextStub());
-
-        $transformer->toEvent('anEvent', new NullMessage());
-    }
-
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|PsrContext
+     * @return MockObject|Context
      */
     private function createContextStub()
     {
-        $context = $this->createMock(PsrContext::class);
+        $context = $this->createMock(Context::class);
         $context
             ->expects($this->any())
             ->method('createMessage')
diff --git a/Tests/ProxyEventDispatcherTest.php b/Tests/ProxyEventDispatcherTest.php
index 5e5c6e9..eed680a 100644
--- a/Tests/ProxyEventDispatcherTest.php
+++ b/Tests/ProxyEventDispatcherTest.php
@@ -5,7 +5,9 @@
 use Enqueue\AsyncEventDispatcher\AsyncEventDispatcher;
 use Enqueue\AsyncEventDispatcher\AsyncListener;
 use Enqueue\Test\ClassExtensionTrait;
+use PHPUnit\Framework\MockObject\MockObject;
 use PHPUnit\Framework\TestCase;
+use Symfony\Component\EventDispatcher\Event;
 use Symfony\Component\EventDispatcher\EventDispatcher;
 use Symfony\Component\EventDispatcher\GenericEvent;
 
@@ -20,7 +22,7 @@ public function testShouldBeSubClassOfEventDispatcher()
 
     public function testShouldSetSyncModeForGivenEventNameOnDispatchAsyncListenersOnly()
     {
-        $asyncListenerMock = $this->createAsyncLisenerMock();
+        $asyncListenerMock = $this->createAsyncListenerMock();
         $asyncListenerMock
             ->expects($this->once())
             ->method('resetSyncMode')
@@ -49,7 +51,7 @@ public function testShouldCallAsyncEventButNotOtherOnDispatchAsyncListenersOnly(
         });
 
         $asyncEventWasCalled = false;
-        $dispatcher = new AsyncEventDispatcher($trueEventDispatcher, $this->createAsyncLisenerMock());
+        $dispatcher = new AsyncEventDispatcher($trueEventDispatcher, $this->createAsyncListenerMock());
         $dispatcher->addListener('theEvent', function () use (&$asyncEventWasCalled) {
             $this->assertInstanceOf(AsyncEventDispatcher::class, func_get_arg(2));
 
@@ -74,13 +76,19 @@ public function testShouldCallOtherEventIfDispatchedFromAsyncEventOnDispatchAsyn
         });
 
         $asyncEventWasCalled = false;
-        $dispatcher = new AsyncEventDispatcher($trueEventDispatcher, $this->createAsyncLisenerMock());
+        $dispatcher = new AsyncEventDispatcher($trueEventDispatcher, $this->createAsyncListenerMock());
         $dispatcher->addListener('theEvent', function () use (&$asyncEventWasCalled) {
             $this->assertInstanceOf(AsyncEventDispatcher::class, func_get_arg(2));
 
             $asyncEventWasCalled = true;
 
-            func_get_arg(2)->dispatch('theOtherEvent');
+            if (!class_exists(Event::class)) {
+                // Symfony 5
+                func_get_arg(2)->dispatch(func_get_arg(0), 'theOtherEvent');
+            } else {
+                // Symfony < 5
+                func_get_arg(2)->dispatch('theOtherEvent');
+            }
         });
 
         $event = new GenericEvent();
@@ -97,7 +105,7 @@ public function testShouldNotCallAsyncEventIfDispatchedFromOtherEventOnDispatchA
             func_get_arg(2)->dispatch('theOtherAsyncEvent');
         });
 
-        $dispatcher = new AsyncEventDispatcher($trueEventDispatcher, $this->createAsyncLisenerMock());
+        $dispatcher = new AsyncEventDispatcher($trueEventDispatcher, $this->createAsyncListenerMock());
         $dispatcher->addListener('theAsyncEvent', function () {
             func_get_arg(2)->dispatch('theOtherEvent');
         });
@@ -113,9 +121,9 @@ public function testShouldNotCallAsyncEventIfDispatchedFromOtherEventOnDispatchA
     }
 
     /**
-     * @return \PHPUnit_Framework_MockObject_MockObject|AsyncListener
+     * @return MockObject|AsyncListener
      */
-    private function createAsyncLisenerMock()
+    private function createAsyncListenerMock()
     {
         return $this->createMock(AsyncListener::class);
     }
diff --git a/Tests/SimpleRegistryTest.php b/Tests/SimpleRegistryTest.php
index 328ed17..c144e74 100644
--- a/Tests/SimpleRegistryTest.php
+++ b/Tests/SimpleRegistryTest.php
@@ -18,15 +18,10 @@ public function testShouldImplementRegistryInterface()
         $this->assertClassImplements(Registry::class, SimpleRegistry::class);
     }
 
-    public function testCouldBeConstructedWithEventsMapAndTransformersMapAsArguments()
-    {
-        new SimpleRegistry([], []);
-    }
-
     public function testShouldAllowGetTransportNameByEventName()
     {
         $registry = new SimpleRegistry([
-                'fooEvent' => 'fooTrans',
+            'fooEvent' => 'fooTrans',
         ], []);
 
         $this->assertEquals('fooTrans', $registry->getTransformerNameForEvent('fooEvent'));
diff --git a/composer.json b/composer.json
index 35e39f3..f78597a 100644
--- a/composer.json
+++ b/composer.json
@@ -1,26 +1,36 @@
 {
     "name": "enqueue/async-event-dispatcher",
     "type": "library",
-    "description": "Symfony async event dispathcer",
+    "description": "Symfony async event dispatcher",
     "keywords": ["messaging", "queue", "async event", "event dispatcher"],
+    "homepage": "https://enqueue.forma-pro.com/",
     "license": "MIT",
     "require": {
-        "php": ">=5.6",
-        "enqueue/enqueue": "^0.8@dev",
-        "symfony/event-dispatcher": "^2.8|^3"
+        "php": "^8.1",
+        "enqueue/enqueue": "^0.10",
+        "queue-interop/queue-interop": "^0.8",
+        "symfony/event-dispatcher": "^5.4|^6.0"
     },
     "require-dev": {
-        "phpunit/phpunit": "~5.5",
-        "symfony/dependency-injection": "^2.8|^3",
-        "symfony/config": "^2.8|^3",
-        "symfony/http-kernel": "^2.8|^3",
-        "symfony/filesystem": "^2.8|^3",
-        "enqueue/null": "^0.8@dev",
-        "enqueue/fs": "^0.8@dev",
-        "enqueue/test": "^0.8@dev"
+        "phpunit/phpunit": "^9.5",
+        "symfony/dependency-injection": "^5.4|^6.0",
+        "symfony/config": "^5.4|^6.0",
+        "symfony/http-kernel": "^5.4|^6.0",
+        "symfony/filesystem": "^5.4|^6.0",
+        "symfony/yaml": "^5.4|^6.0",
+        "enqueue/null": "0.10.x-dev",
+        "enqueue/fs": "0.10.x-dev",
+        "enqueue/test": "0.10.x-dev"
+    },
+    "support": {
+        "email": "opensource@forma-pro.com",
+        "issues": "https://github.com/php-enqueue/enqueue-dev/issues",
+        "forum": "https://gitter.im/php-enqueue/Lobby",
+        "source": "https://github.com/php-enqueue/enqueue-dev",
+        "docs": "https://github.com/php-enqueue/enqueue-dev/blob/master/docs/index.md"
     },
     "suggest": {
-        "symfony/dependency-injection": "^2.8|^3 If you'd like to use async event dispatcher container extension."
+        "symfony/dependency-injection": "^5.4|^6.0 If you'd like to use async event dispatcher container extension."
     },
     "autoload": {
         "psr-4": { "Enqueue\\AsyncEventDispatcher\\": "" },
@@ -30,7 +40,7 @@
     },
     "extra": {
         "branch-alias": {
-            "dev-master": "0.8.x-dev"
+            "dev-master": "0.10.x-dev"
         }
     }
 }
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index e64c86d..e5c3f6d 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -1,16 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 
-<phpunit backupGlobals="false"
-         backupStaticAttributes="false"
-         colors="true"
-         convertErrorsToExceptions="true"
-         convertNoticesToExceptions="true"
-         convertWarningsToExceptions="true"
-         processIsolation="false"
-         stopOnFailure="false"
-         syntaxCheck="false"
-         bootstrap="./vendor/autoload.php"
-        >
+<phpunit
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/7.5/phpunit.xsd"
+    colors="true"
+    bootstrap="./vendor/autoload.php"
+>
 
     <testsuites>
         <testsuite name="Symfony Async Event Dispatcher Test Suite">
