private async Task OnEventDelivered(EventStoreSubscription subscription, ResolvedEvent resolvedEvent)
        {
            if (!_typeResolver.TryGetType(resolvedEvent.Event.EventType, out var eventType))
            {
                return;
            }
            if (!_subscribedEventTypes.Contains(eventType))
            {
                return;
            }
            var @event = _deserializer.Deserialize(resolvedEvent, eventType);

            foreach (var eventProcessor in _eventProcessors)
            {
                await eventProcessor.ProcessAsync(@event);
            }
        }
        /// <summary>
        /// Tries to retrieve type by it's name and generic parameters.
        /// </summary>
        /// <param name="typeReference">Type name. Not null. Not <see cref="TypeReference.Empty"/></param>
        /// <param name="foundType">Found type or null.</param>
        /// <returns>True if type is found. Overwise is false.</returns>
        public bool TryGetType(TypeReference typeReference, out Type foundType)
        {
            foundType = default(Type);

            var matches             = 0;
            var genericTypeRequired = typeReference.TypeArguments.Count > 0;
            var typesToCheck        = default(List <Type>);

            if (this.knownTypesByFullName.TryGetValue(typeReference.FullName, out typesToCheck))
            {
                foreach (var type in typesToCheck)
                {
                    if (genericTypeRequired != type.IsGenericType)
                    {
                        continue;
                    }
                    if (genericTypeRequired && type.GetGenericArguments().Length != typeReference.TypeArguments.Count)
                    {
                        continue;
                    }

                    if (foundType != type)                      // could be same type
                    {
                        matches++;
                    }
                    foundType = type;
                }
            }
            if (this.knownTypesByName.TryGetValue(typeReference.FullName, out typesToCheck))
            {
                foreach (var type in typesToCheck)
                {
                    if (genericTypeRequired != type.IsGenericType)
                    {
                        continue;
                    }
                    if (genericTypeRequired && type.GetGenericArguments().Length != typeReference.TypeArguments.Count)
                    {
                        continue;
                    }

                    if (foundType != type)                     // could be same type
                    {
                        matches++;
                    }
                    foundType = type;
                }
            }

            if (foundType == null && (string.Equals(typeReference.FullName, ArrayFullName, StringComparison.Ordinal) || string.Equals(typeReference.Name, ArrayName, StringComparison.Ordinal)))
            {
                foundType = typeof(Array);
                matches   = 1;
            }

            if (foundType == null && otherTypeResolver != null)
            {
                otherTypeResolver.TryGetType(typeReference, out foundType);
                matches = foundType != null ? 1 : 0;
            }

            if (matches != 1)
            {
                foundType = null;
                return(false);
            }

            if (foundType == typeof(Array))
            {
                if (typeReference.TypeArguments.Count == 1)
                {
                    var elementType = default(Type);
                    if (this.TryGetType(typeReference.TypeArguments[0], out elementType) == false)
                    {
                        return(false);
                    }

                    foundType = elementType.MakeArrayType();
                    return(true);
                }
                else if (typeReference.TypeArguments.Count == 0)
                {
                    return(true);
                }
                foundType = null;
            }
            else if (foundType != null && typeReference.TypeArguments.Count > 0)
            {
                var genericParameters = default(Type[]);
                if (foundType.IsGenericType && (genericParameters = foundType.GetGenericArguments()).Length == typeReference.TypeArguments.Count)
                {
                    var typeArguments    = new Type[genericParameters.Length];
                    var allArgumentBound = true;
                    var isOpenType       = true;
                    for (var i = 0; i < typeArguments.Length; i++)
                    {
                        var genericArgumentTypeReference = typeReference.TypeArguments[i];
                        if (genericArgumentTypeReference == TypeReference.Empty)
                        {
                            typeArguments[i] = genericParameters[i];
                        }
                        else if (this.TryGetType(genericArgumentTypeReference, out typeArguments[i]))
                        {
                            isOpenType = false;
                        }
                        else
                        {
                            allArgumentBound = false;
                        }
                    }

                    if (!foundType.IsGenericTypeDefinition)
                    {
                        foundType = foundType.GetGenericTypeDefinition() ?? foundType;
                    }

                    if (allArgumentBound)
                    {
                        foundType = isOpenType ? foundType : foundType.MakeGenericType(typeArguments);
                        return(true);
                    }
                }
                foundType = null;
            }

            return(foundType != null);
        }