/// <summary>
        /// Checks a list of components for validity.
        /// </summary>
        /// <typeparam name="T">Entity type</typeparam>
        /// <typeparam name="TListElement">Type of list element</typeparam>
        /// <param name="spec">Persistence specification</param>
        /// <param name="expression">Property</param>
        /// <param name="propertyValue">Value to save</param>
        /// <param name="elementComparer">Equality comparer</param>
        public static PersistenceSpecification <T> CheckComponentList <T, TListElement>(this PersistenceSpecification <T> spec,
                                                                                        Expression <Func <T, object> > expression,
                                                                                        IEnumerable <TListElement> propertyValue,
                                                                                        IEqualityComparer elementComparer)
        {
            Accessor property = ReflectionHelper.GetAccessor(expression);

            return(spec.RegisterCheckedProperty(new List <T, TListElement>(property, propertyValue), elementComparer));
        }
        public static PersistenceSpecification <T> CheckReference <T, TReference>(this PersistenceSpecification <T> spec,
                                                                                  Expression <Func <T, TReference> > expression,
                                                                                  TReference propertyValue,
                                                                                  IEqualityComparer propertyComparer)
        {
            Accessor property = ReflectionHelper.GetAccessor(expression);

            return(spec.RegisterCheckedProperty(new ReferenceProperty <T, TReference>(property, propertyValue), propertyComparer));
        }
        public static PersistenceSpecification <T> CheckProperty <T, TProperty>(this PersistenceSpecification <T> spec,
                                                                                Expression <Func <TProperty> > expression,
                                                                                IEqualityComparer propertyComparer)
        {
            Accessor  property      = ReflectionHelper.GetAccessor(expression);
            TProperty propertyValue = expression.Compile().Invoke();

            return(spec.RegisterCheckedProperty(new Property <T, TProperty>(property, propertyValue), propertyComparer));
        }
        public static PersistenceSpecification <T> CheckProperty <T, TProperty>(this PersistenceSpecification <T> spec,
                                                                                Expression <Func <T, TProperty> > expression,
                                                                                TProperty propertyValue,
                                                                                IEqualityComparer propertyComparer)
        {
            Accessor property = ReflectionHelper.GetAccessor(expression);

            if (typeof(TProperty).IsArray)
            {
                // Func matching return value as TProperty is more specific than matching Array or TListElement[],
                // so have to use reflection in array case instead of relying on generic matching.
                return(spec.RegisterCheckedProperty(ListConstructor <T, TProperty> .Create(property, propertyValue), propertyComparer));
            }
            else
            {
                return(spec.RegisterCheckedProperty(new Property <T, TProperty>(property, propertyValue), propertyComparer));
            }
        }
        public static PersistenceSpecification <T> CheckProperty <T, TProperty>(this PersistenceSpecification <T> spec,
                                                                                Expression <Func <T, TProperty> > expression,
                                                                                TProperty propertyValue,
                                                                                IEqualityComparer propertyComparer,
                                                                                Action <T, TProperty> propertySetter)
        {
            Accessor propertyInfoFromExpression = ReflectionHelper.GetAccessor(expression);

            var property = new Property <T, TProperty>(propertyInfoFromExpression, propertyValue);

            property.ValueSetter = (target, propertyInfo, value) => propertySetter(target, value);

            return(spec.RegisterCheckedProperty(property, propertyComparer));
        }
        public static PersistenceSpecification <T> CheckComponentList <T, TListElement>(this PersistenceSpecification <T> spec,
                                                                                        Expression <Func <T, IEnumerable <TListElement> > > expression,
                                                                                        IEnumerable <TListElement> propertyValue,
                                                                                        IEqualityComparer elementComparer,
                                                                                        Action <T, IEnumerable <TListElement> > listSetter)
        {
            Accessor property = ReflectionHelper.GetAccessor(expression);

            var list = new List <T, TListElement>(property, propertyValue);

            list.ValueSetter = (target, propertyInfo, value) => listSetter(target, value);

            return(spec.RegisterCheckedProperty(list, elementComparer));
        }
        public static PersistenceSpecification <T> CheckBag <T, TListElement>(this PersistenceSpecification <T> spec,
                                                                              Expression <Func <T, IEnumerable <TListElement> > > expression,
                                                                              IEnumerable <TListElement> propertyValue,
                                                                              IEqualityComparer elementComparer,
                                                                              Action <T, TListElement> listItemSetter)
        {
            Accessor property = ReflectionHelper.GetAccessor(expression);

            var list = new ReferenceBag <T, TListElement>(property, propertyValue);

            list.ValueSetter = (target, propertyInfo, value) =>
            {
                foreach (var item in value)
                {
                    listItemSetter(target, item);
                }
            };

            return(spec.RegisterCheckedProperty(list, elementComparer));
        }