/// <summary>
        /// Checks that <paramref name="source"/> declares public properties of <paramref name="target"/>, using the
        /// property name as the matching criteria, skipping any properties on target explicitly ignored.
        /// </summary>
        /// <param name="source">The source object to check for properties declared on target</param>
        /// <param name="target">target object whose public properties must be declared on source</param>
        /// <param name="options">optional options that determine which properties on target should be considered in check</param>
        /// <param name="ignore">optional list of properties to ignore on target when performing the check</param>
        /// <exception cref="PreconditionException">Thrown on the first occurance of a property that <paramref name="source"/> does not declare</exception>
        public static void RequirePublicPropertyNamesOf <T>(this object source,
                                                            T target,
                                                            RequirePropertyOptions options,
                                                            params Expression <Func <T, object> >[] ignore)
        {
            options = options ?? new RequirePropertyOptions();

            IEnumerable <string> propertiesToIgnore =
                ignore.SafeToList().Select(x => ReflectionUtil.GetAccessor(x).Name);

            var candidateTargetProperties =
                from p in ReflectionUtil.GetPublicInstanceProperties(target)
                where !options.IgnoreReadonly || p.CanWrite
                select p.Name;
            IEnumerable <string> targetProperties = candidateTargetProperties.Except(propertiesToIgnore);

            ReflectionUtil.GetActualType(source).RequireProperties(targetProperties);
        }
 /// <seealso cref="RequirePublicPropertyNamesOf{T}(object,T,Eca.Commons.Extensions.RequirePropertyOptions,System.Linq.Expressions.Expression{System.Func{T,object}}[])"/>
 public static void RequireAllPublicPropertyNamesOf(this object source,
                                                    object target,
                                                    RequirePropertyOptions options)
 {
     RequirePublicPropertyNamesOf(source, target, options, null);
 }