/// <summary>Find out if a principal has a certain permission for an item.</summary>
        /// <param name="item">The item to check against.</param>
        /// <param name="user">The principal to check for allowance.</param>
        /// <param name="permission">The type of permission to map against.</param>
        /// <returns>True if the item has public access or the principal is allowed to access it.</returns>
        public virtual bool IsAuthorized(IPrincipal user, ContentItem item, Permission permission)
        {
            if (permission == Permission.None)
            {
                return(true);
            }
            if (item == null)
            {
                return(IsAuthorized(user, permission));
            }
            if (permission == Permission.Read)
            {
                return(IsAuthorized(item, user));
            }

            foreach (PermissionRemapAttribute remap in item.GetContentType().GetCustomAttributes(typeof(PermissionRemapAttribute), true))
            {
                permission = remap.Remap(permission);
            }

            return(Administrators.Authorizes(user, item, permission) ||
                   Editors.Authorizes(user, item, permission) ||
                   Writers.Authorizes(user, item, permission));
        }