public Yield GetComment(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PageBE    page      = null;
            CommentBE comment   = null;
            var       commentId = context.GetParam <uint>("commentid", 0);

            if (commentId > 0)
            {
                comment = CommentBL.GetComment(commentId);
            }
            else
            {
                GetCommentFromRequest(context, Permissions.READ, out page, out comment);
            }
            response.Return(DreamMessage.Ok(CommentBL.GetCommentXml(comment, null)));
            yield break;
        }
        public Yield PostPageComment(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PageBE page = PageBL_AuthorizePage(context, null, Permissions.READ, false);

            if (UserBL.IsAnonymous(DekiContext.Current.User))
            {
                throw new CommentPostForAnonymousDeniedException(AUTHREALM, string.Empty);
            }
            CommentBE comment = CommentBL.PostNewComment(page, request, context);

            if (comment != null)
            {
                DekiContext.Current.Instance.EventSink.CommentCreate(DekiContext.Current.Now, comment, page, DekiContext.Current.User);
                response.Return(DreamMessage.Ok(CommentBL.GetCommentXml(comment, null)));
            }
            else
            {
                throw new CommentFailedPostFatalException();
            }
            yield break;
        }
        public Yield PutCommentContent(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PageBE    page    = null;
            CommentBE comment = null;

            GetCommentFromRequest(context, Permissions.READ, out page, out comment);
            if (UserBL.IsAnonymous(DekiContext.Current.User))
            {
                throw new CommentPostForAnonymousDeniedException(AUTHREALM, string.Empty);
            }
            comment = CommentBL.EditExistingComment(page, comment, request, context);
            if (comment != null)
            {
                DekiContext.Current.Instance.EventSink.CommentUpdate(DekiContext.Current.Now, comment, page, DekiContext.Current.User);
                response.Return(DreamMessage.Ok(CommentBL.GetCommentXml(comment, null)));
            }
            else
            {
                throw new CommentFailedEditFatalException();
            }
            yield break;
        }
        public Yield GetPageComments(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            CheckResponseCache(context, false);

            PageBE page = PageBL_AuthorizePage(context, null, Permissions.READ, false);
            uint   count, offset;

            string        filterStr = context.GetParam("filter", "nondeleted");
            CommentFilter filter;

            switch (filterStr.ToLowerInvariant())
            {
            case "any":
                filter = CommentFilter.ANY;
                break;

            case "nondeleted":
                filter = CommentFilter.NONDELETED;
                break;

            default:
                throw new CommentFilterInvalidArgumentException();
            }
            bool   includeDescendantPages = false;
            string depth = context.GetParam("depth", "0");

            switch (depth.ToLowerInvariant())
            {
            case "0":
                includeDescendantPages = false;
                break;

            case "infinity":
                includeDescendantPages = true;
                break;

            default:
                throw new DreamBadRequestException(string.Format("Invalid depth value '{0}'. Supported values are '0' and 'infinity'.", depth));
            }

            uint postedByUserIdtmp = context.GetParam <uint>("postedbyuserid", 0);
            uint?postedByUserId    = null;

            if (postedByUserIdtmp > 0)
            {
                postedByUserId = postedByUserIdtmp;
            }

            SortDirection sortDir;
            string        sortField;

            Utils.GetOffsetAndCountFromRequest(context, 100, out count, out offset, out sortDir, out sortField);
            sortDir = sortDir == SortDirection.UNDEFINED ? SortDirection.ASC : sortDir; // default sort is ascending by timestamp
            uint totalCount;
            XUri commentsUri           = DekiContext.Current.ApiUri.At("pages", page.ID.ToString(), "comments");
            IList <CommentBE> comments = CommentBL.RetrieveCommentsForPage(page, filter, includeDescendantPages, postedByUserId, sortDir, offset, count, out totalCount);

            XDoc     ret = null;
            MimeType mimetype;

            switch (context.GetParam("format", "xml").ToLowerInvariant())
            {
            case "xml":
                ret      = CommentBL.GetCommentXml(comments, true, null, includeDescendantPages, offset, sortDir, null, commentsUri, totalCount);
                mimetype = MimeType.XML;
                break;

            case "atom":
                ret      = CommentBL.GetCommentXmlAsAtom(comments, context.Uri, page);
                mimetype = MimeType.ATOM;
                break;

            default:
                throw new DreamBadRequestException("Invalid format. Valid formats are 'xml' and 'atom'.");
            }

            response.Return(DreamMessage.Ok(mimetype, ret));
            yield break;
        }