private ResourceBE GetAttachmentFromUrl(DreamContext context, bool mustExist, out PageBE page, bool allowRevs, bool allowDeleted)
        {
            ResourceBE file     = null;
            int        revision = ResourceBE.HEADREVISION;

            page = null;
            string revStr = DreamContext.Current.GetParam("revision", "head").Trim();

            if (allowRevs)
            {
                if (!StringUtil.EqualsInvariantIgnoreCase(revStr, "head") && !StringUtil.EqualsInvariantIgnoreCase(revStr, "0"))
                {
                    if (!int.TryParse(revStr, out revision))
                    {
                        throw new RevisionHeadOrIntInvalidArgumentException();
                    }
                }
            }
            else if (!StringUtil.EqualsInvariantIgnoreCase(revStr, "head") && !StringUtil.EqualsInvariantIgnoreCase(revStr, "0"))
            {
                throw new AttachmentUnsupportedRevisionInvalidArgumentException();
            }

            uint fileId = DreamContext.Current.GetParam <uint>("fileid", 0);

            if (fileId != 0)
            {
                uint resourceId = ResourceMapBL.GetResourceIdByFileId(fileId) ?? 0;
                if (resourceId > 0)
                {
                    // use resourceid to retrieve attachment
                    file = ResourceBL.Instance.GetResourceRevision(resourceId, revision);
                }
                if (file != null)
                {
                    page = PageBL.GetPageById(file.ParentPageId.Value);
                }
            }
            else
            {
                // use filename to retrieve attachment
                string fileName = GetFilenameFromPathSegment(DreamContext.Current.GetParam <string>("filename"));
                page = PageBL_GetPageFromUrl(context, true);
                DeletionFilter deleteFilter = allowDeleted ? DeletionFilter.ANY : DeletionFilter.ACTIVEONLY;
                file = AttachmentBL.Instance.GetPageAttachment(page.ID, fileName, deleteFilter);
                if (revision != ResourceBE.HEADREVISION)
                {
                    file = ResourceBL.Instance.GetResourceRevision(file.ResourceId, revision);
                }
            }
            if (file == null)
            {
                if (mustExist)
                {
                    throw new AttachmentNotFoundException();
                }
            }
            else
            {
                if (!allowDeleted)
                {
                    if (file.ResourceIsDeleted || page == null)
                    {
                        // TODO (maxm): Throw a 404 status if file is not marked as deleted but the parent page cannot be found.
                        // This may be caused by an unfinished page delete operation that didn't mark the file as deleted.
                        throw new AttachmentRemovedNotFoundException();
                    }
                }
            }

            return(file);
        }
        //--- Methods ---
        public void Append(XDoc exportDoc)
        {
            _manifestDoc.Attr("date.created", DateTime.UtcNow).Attr("preserve-local", false);
            foreach (XDoc exportXml in exportDoc.Elements)
            {
                // Retrieve the current page
                try {
                    if (exportXml.HasName("page"))
                    {
                        // Generate the manifest and request needed to export the page
                        PageBE page = null;
                        if (!exportXml["@id"].IsEmpty)
                        {
                            uint pageId = DbUtils.Convert.To <uint>(exportXml["@id"].Contents, 0);
                            if (0 < pageId)
                            {
                                page = PageBL.GetPageById(pageId);
                            }
                        }
                        else if (!exportXml["@path"].IsEmpty)
                        {
                            page = PageBL.GetPageByTitle(Title.FromPrefixedDbPath(exportXml["@path"].Contents, null));
                        }
                        if ((null == page) || (0 == page.ID))
                        {
                            throw new PageNotFoundException();
                        }

                        // Check whether to exclude subpages, files, and/or properties
                        bool recursive            = exportXml["@recursive"].AsBool ?? false;
                        ExportExcludeType exclude = ExportExcludeType.NONE;
                        if (!exportXml["@exclude"].IsEmpty)
                        {
                            exclude = SysUtil.ChangeType <ExportExcludeType>(exportXml["@exclude"].Contents);
                        }

                        // Export the page
                        PageExport(recursive, exclude, page);
                    }
                    else if (exportXml.HasName("file"))
                    {
                        // Generate the manifest and request needed to export the file
                        ResourceBE file = null;
                        if (!exportXml["@id"].IsEmpty)
                        {
                            uint fileId = DbUtils.Convert.To <uint>(exportXml["@id"].Contents, 0);
                            if (0 < fileId)
                            {
                                uint resourceId = ResourceMapBL.GetResourceIdByFileId(fileId) ?? 0;
                                if (resourceId > 0)
                                {
                                    file = ResourceBL.Instance.GetResource(resourceId);
                                }
                            }
                        }
                        if (null == file)
                        {
                            throw new AttachmentNotFoundException();
                        }

                        // Check whether to exclude properties
                        ExportExcludeType exclude = ExportExcludeType.NONE;
                        if (!exportXml["@exclude"].IsEmpty)
                        {
                            exclude = SysUtil.ChangeType <ExportExcludeType>(exportXml["@exclude"].Contents);
                        }

                        // Perform the file export
                        PageBE page = PageBL.GetPageById(file.ParentPageId.Value);
                        page = PageBL.AuthorizePage(DekiContext.Current.User, Permissions.READ, page, false);
                        AttachmentExport(exclude, page, file);
                    }
                    else
                    {
                        throw new DreamResponseException(DreamMessage.NotImplemented(exportXml.Name));
                    }
                } catch (ResourcedMindTouchException e) {
                    AddError(e.Message, (int)e.Status, exportXml);
                } catch (DreamAbortException e) {
                    AddError(e.Message, (int)e.Response.Status, exportXml);
                } catch (Exception e) {
                    AddError(e.Message, (int)DreamStatus.InternalError, exportXml);
                }
            }
        }