anchor.diff:  The various objects and their properties are documented in much more detail here:
   https://github.com/commonsmachinery/catalog/blob/master/doc/datamodel/core.md
   
  -## Media [/media/{mediaID}{?annotations}]
  -A media instance, which is a read-only record of a particular media instance of a Work
  -at the time it was recorded in the catalog.
  -
  -Media instances are intended to be the "raw material" of Works, so access to them
  -may be restricted in the catalog to require a reference via a Work (see Work Media below).
  +## Work [/works/{workID}{?include,annotations}]
  +A work record.
  +
  +The annotations can either be manipulated via the sublist in the document, 
  +or via the separate Annotation collection endpoint.
  +
  +The Media instances linked to this work can be (and may be required to be)
  +accessed via the Work.  See the Work Media endpoints below.  The list of Media instances
  +in the `media` property always use URLs referencing such an endpoint.  
  +
  +When adding another Work's Media to this Work, add the Work Media endpoint for that other
  +work to the `media` list.  It will be rewritten to the Media endpoint for the target Work.
   
   To make the annotations easier to use in web pages the parameter `annotations` can be set
   to a list of property names, e.g. `title,locator`.  This will change the response from a plain list to a map, only
  
positive.code: e.g. a title without having to dig through the list.
  
  + Parameters
      + annotations (string, optional) ... Select properties to get or update in map.
  
  + Model
      + Headers
      
              Link: <https://catalog.elog.io/media/6e1ee592539d7d163613d732>;rel="self"
  
      + Body
  
              {
                  "id": "6e1ee592539d7d163613d732",
                  "added_by": "https://catalog.elog.io/users/someUserID",
                  "added_at": "2014-04-14T02:15:15Z",
                  "replaces": "https://catalog.elog.io/media/prevMediaID",
                  "annotations": [{
                          "id": "63613d7321ee5396e592d7d1",
                          "updated_by": "https://catalog.elog.io/users/anotherUserID",
                          "updated_at": "2014-04-14T02:15:15Z",
                          "score": 100,
                          "property": {
                              "propertyName": "title",
                              "titleLabel": "Title of the work",
                          }
                      }],
                  "metadata": {
                          "xmp": "<?xml...",
                          "oembed": { "url": "http://some/photo.jpg" }
                      }
              }
  
  ### Retrieve a Media [GET]
  + Response 200 (application/json)
      [Media][]
  
  
  ## Media collection [/media{?offset,count,filter,sort,annotations}]
  Given the role of Media as mainly internal raw material means that it often makes more sense to use
  the Work Media collection instead of this one (see below).
  
  
  ### List Media instances [GET]
  TODO: define filters and sorting.
  
  Pagination is supported by returning a `Link` header with links according to 
  http://tools.ietf.org/html/rfc5005
  
  + Parameters
      + offset (number, optional) ... Skip this many records in the result. Default: 0
      + count (number, optional) ... Return this many records. Default and max values are system-dependent.
      + filter (string, optional) ... Filter responses (see above). Default: no filter.
      + sort (string, optional) ... Sort response (see above). Default: "natural" sort.
      + annotations (string, optional) ... Select properties to get in response.
  
  + Response 200 (application/json)
      + Headers
      
              Link: <?offset=0&count=N&...>;rel="first", <?offset=Z&count=N&...>;rel="last", <?offset=X&count=N&...>;rel="previous", <?offset=Y&count=N&...>;rel="next"
  
      + Body
      
              []
  
  ### Create new Media instances [POST]
  Since creating a Media without a Work may not make much sense in some cases, 
  this endpoint might be disabled in the catalog.
  
  Only the following properties in the request will be used:
  
      - annotations (empty list if omitted)
      - metadata (empty object if omitted)
      - replaces (null if omitted)
  
  + Request (application/json)
      [Media][]
      
  + Response 201 (application/json)
      [Media][]
      
  
  ## Create Media from an uploaded file [/media/actions/upload{?email}]
  
  Instead of extracting all the metadata from the file locally, the catalog may provide the
  service to clients to upload files for server-side processing instead.  This either requires an 
  active session for a user, or an email address to be provided in the request.  In both cases an email
  will be sent to the user when the file has been processed with a link to confirm the uploaded data.
  
  ### Upload file [POST]
  
  TODO: is this a sane way to upload files, or should multi-part requests be used instead?  
  Or is this really up to the client's discretion and we should accept both?
  
  + Parameters
      + email (string, optional) ... Uploader email, if there isn't already an active user session.
      
  + Request (mime-type/of-file)
  
          <file contents>
  
  + Response 202 (application/json)
  
          { "confirm_email": "foo@example.org" }
          
  
  ## Create Media from an online source [/media/actions/fetch{?url,email}]
  
  Similar to uploading a file, this fetches information about a work that's available at a URL online
  and sends a confirmation email when the processing is finished.
  
  ### Fetch online source [POST]
  
  + Parameters
      + url (optional, string) ... The URL, if not specified in the request body.
      + email (string, optional) ... User email, if not specified in the request body and there isn't already an active user session.
  
  + Request (application/json)
  
          { "url": "http://some/where", "email": "foo@example.org" }
          
  + Request (application/x-www-form-urlencoded)
  
          url=http://some/where&email=foo@example.org
  
  + Response 202 (application/json)
  
          { "confirm_email": "foo@example.org" }
  
  
  ## Work [/works/{id}{?include,annotations}]
  A work record.
  
  The annotations can either be manipulated via the sublist in the document, 
  or via the separate Annotation collection endpoint.
  
  The Media instances linked to this work can be (and may be required to be)
  accessed via the Work.  See the Work Media endpoints below.  The list of Media instances
  in the `media` property always use URLs referencing such an endpoint.  
  
  When adding another Work's Media to this Work, add the Work Media endpoint for that other
  work to the `media` list.  It will be rewritten to the Media endpoint for the target Work.
  
  To make the annotations easier to use in web pages the parameter `annotations` can be set
  to a list of property names, e.g. `title,locator`.  This will change the response from a plain list to a map, only
  including the listed properties.  (`all` means that all properties are included in the map.)
  The keys in this map are the `propertyName`, and the value a list of the Annotations for
  that property.  This allows easy access like `annotations.title[0].property.value` to show
  e.g. a title without having to dig through the list.
  
  + Parameters
      + id (string) ... Work record ID
      + include (string, optional) ... Which sublists to include in the response objects. 
          If omitted or empty, all lists are returned in full.  If `none`, all are omitted.
          Otherwise acomma-separated names: `collaborators`, `annotations`, `sources`, `media`.
  
negative.code:     [Work][]
  
  
  ## Create Work from an uploaded file [/works/actions/upload{?email}]
  
  Instead of extracting all the metadata from a file locally, the catalog may provide the
  service to clients to upload files for server-side processing instead. This either requires an
  active session for a user, or an email address to be provided in the request. In both cases an email
  will be sent to the user when the file has been processed with a link to confirm the uploaded data.
  
  ### Upload file [POST]
  
  TODO: is this a sane way to upload files, or should multi-part requests be used instead?
  Or is this really up to the client's discretion and we should accept both?
  
  + Parameters
      + email (string, optional) ... Uploader email, if there isn't already an active user session.
      
  + Request (mime-type/of-file)
  
          <file contents>
  
  + Response 202 (application/json)
  
          { "confirm_email": "foo@example.org" }
          
  
  ## Create Work from an online source [/works/actions/fetch{?url,email}]
  
  Similar to uploading a file, this fetches information about a work that's available at a URL online
  and sends a confirmation email when the processing is finished.
  
  ### Fetch online source [POST]
  
  + Parameters
      + url (optional, string) ... The URL, if not specified in the request body.
      + email (string, optional) ... User email, if not specified in the request body and there isn't already an active user session.
  
  + Request (application/json)
  
          { "url": "http://some/where", "email": "foo@example.org" }
          
  + Request (application/x-www-form-urlencoded)
  
          url=http://some/where&email=foo@example.org
  
  + Response 202 (application/json)
  
          { "confirm_email": "foo@example.org" }
  
  
  
  ## Media [/works/{workID}/media/{mediaID}{?annotations}]
  A media instance, which is a read-only record of a particular media instance of a Work
  at the time it was recorded in the catalog.
  
  A given Media instance can be linked to multiple works (e.g. when a Work is forked, or just
  if it is added multiple times by different people from the same media source).  The instances will
  all have the same ID, but must always be accessed via one of the works to determine visibility.
  
  To make the annotations easier to use in web pages the parameter `annotations` can be set
  to a list of property names, e.g. `title,locator`.  This will change the response from a plain list to a map, only
  including the listed properties.  (`all` means that all properties are included in the map.)
  The keys in this map are the `propertyName`, and the value a list of the Annotations for
  that property.  This allows easy access like `annotations.title[0].property.value` to show
  e.g. a title without having to dig through the list.
  
  + Parameters
      + annotations (string, optional) ... Select properties to get or update in map.
  
  + Model
      + Headers
      
              Link: <https://catalog.elog.io/media/6e1ee592539d7d163613d732>;rel="self"
  
      + Body
  
              {
                  "id": "6e1ee592539d7d163613d732",
                  "added_by": "https://catalog.elog.io/users/someUserID",
                  "added_at": "2014-04-14T02:15:15Z",
                  "replaces": "https://catalog.elog.io/media/prevMediaID",
                  "annotations": [{
                          "id": "63613d7321ee5396e592d7d1",
                          "updated_by": "https://catalog.elog.io/users/anotherUserID",
                          "updated_at": "2014-04-14T02:15:15Z",
                          "score": 100,
                          "property": {
                              "propertyName": "title",
                              "titleLabel": "Title of the work",
                          }
                      }],
                  "metadata": {
                          "xmp": "<?xml...",
                          "oembed": { "url": "http://some/photo.jpg" }
                      }
              }
  
  ### Retrieve a Media [GET]
  + Response 200 (application/json)
      [Media][]
  
  
  ### Unlink a Media from a Work [DELETE]
  This does not delete the underlying Media instance, just the link to it.
  If this was the last link to the Media, it will be garbage collected eventually.
  
  + Response 204
  
  
  ## Media collection [/works/{workID}/media{?annotations}]
  
  All the Media instances linked to this work.
  
  + Parameters
      + workID (string) ... Work ID whose Media are manipulated
      + annotations (string, optional) ... Select properties to get in response.
  
  ### List Work Media [GET]
  Return all Media instances of the Work.
  