public ModelAttributesInfo(Type modelType)
        {
            QueryAuthAttributes      = GetAuthAttributesOfClassOrDirectTopClass <QueryAuthAttribute>(modelType);
            QueryEntryAuthAttributes = GetAuthAttributesOfClassOrDirectTopClass <QueryEntryAuthAttribute>(modelType);
            UpdateAuthAttributes     = GetAuthAttributesOfClassOrDirectTopClass <UpdateAuthAttribute>(modelType);
            RemoveAuthAttributes     = GetAuthAttributesOfClassOrDirectTopClass <RemoveAuthAttribute>(modelType);
            CreateAuthAttributes     = GetAuthAttributesOfClassOrDirectTopClass <CreateAuthAttribute>(modelType);

            CreateEventAttributes = GetHookAttributeOfClassAndTopClasses <CreateEventAttribute>(modelType);
            UpdateEventAttributes = GetHookAttributeOfClassAndTopClasses <UpdateEventAttribute>(modelType);
            RemoveEventAttributes = GetHookAttributeOfClassAndTopClasses <RemoveEventAttribute>(modelType);

            QueryFunctionAttribute = modelType.GetCustomAttribute <QueryFunctionAttribute>(false);
            QueryFunctionAttribute?.Compile(modelType);

            UpdatableAttribute = modelType.GetCustomAttribute <UpdatableAttribute>(false);
        }
        public void HandleCollections(ConnectionBase connection, string contextName, Type dbContextType,
                                      List <ChangeResponse> changes, IServiceProvider requestServiceProvider)
        {
            IEnumerable <IGrouping <string, CollectionSubscription> > subscriptionGroupings = connection.Subscriptions
                                                                                              .Where(s => s.ContextName == contextName)
                                                                                              .GroupBy(s => s.CollectionName);

            foreach (IGrouping <string, CollectionSubscription> subscriptionGrouping in subscriptionGroupings)
            {
                KeyValuePair <Type, string> property = dbContextType.GetDbSetType(subscriptionGrouping.Key);

                List <ChangeResponse> changesForCollection = changes
                                                             .Where(c => c.CollectionName == subscriptionGrouping.Key)
                                                             .ToList();

                AuthModelInfo modelInfo = property.Key.GetAuthModelInfos();

                IEnumerable <ChangeResponse> authenticatedChanges = changesForCollection;

                if (modelInfo.QueryEntryAuthAttributes.Any())
                {
                    authenticatedChanges = changesForCollection
                                           .Where(change => change.State == ChangeResponse.ChangeState.Deleted ||
                                                  property.Key.CanQueryEntry(connection.Information, requestServiceProvider,
                                                                             change.Value));


                    IEnumerable <ChangeResponse> oldLoadedNotAllowed = changesForCollection
                                                                       .Where(change => change.State == ChangeResponse.ChangeState.Modified &&
                                                                              !property.Key.CanQueryEntry(connection.Information, requestServiceProvider,
                                                                                                          change.Value))
                                                                       .Select(change =>
                    {
                        ChangeResponse newChangeResponse = change.CreateResponse(null, change.Value);
                        newChangeResponse.State          = ChangeResponse.ChangeState.Deleted;
                        return(newChangeResponse);
                    });

                    authenticatedChanges = authenticatedChanges.Concat(oldLoadedNotAllowed);
                }

                List <ChangeResponse> collectionChanges = authenticatedChanges.ToList();

                if (collectionChanges.Any())
                {
                    QueryFunctionAttribute queryFunctionAttribute =
                        property.Key.GetCustomAttribute <QueryFunctionAttribute>(false);
                    if (queryFunctionAttribute != null)
                    {
                        var queryFunctionInfo = property.Key.GetMethod(queryFunctionAttribute.Function,
                                                                       BindingFlags.Default | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);

                        if (queryFunctionInfo != null)
                        {
                            object[] methodParameters =
                                queryFunctionInfo.CreateParameters(connection.Information, serviceProvider);
                            dynamic queryFunctionExpression =
                                ((dynamic)queryFunctionInfo.Invoke(null, methodParameters)).Compile();

                            collectionChanges = collectionChanges.Where(change => queryFunctionExpression(change.Value))
                                                .ToList();
                        }
                    }
                }

                foreach (CollectionSubscription subscription in subscriptionGrouping)
                {
                    Task.Run(() =>
                    {
                        HandleSubscription(subscription, dbContextType, requestServiceProvider, connection,
                                           property, collectionChanges, changes);
                    });
                }
            }
        }