Add support for "variant" operation arguments

Declared as a set() of accepted types.  This overloads the existing use
of set() (of strings) for "enumerated values", but compatibly so.  Before
this change, any set() not containing only strings would have triggered
an error, and after this change a set() containing only strings work the
same way as before.
Add Operation.requireRole() helper function

Raises an OperationFailure exception saying "Operation not permitted" if
the user doesn't have the required role.
Add support for non-obtrusive client-side notifications

Add function showNotification() that client-side scripts can use to show
a non-obstrusive "notification" style message.  Currently displayed (fixed
positioned) at the top of the page for a few seconds, then fades away.
Display delegates value in human-readable form

Or, actually, just add a space after the commas.  This helps formatting
by allowing the client to line-break between names.
Run installation.prefs after installation.migrate

Motivation: it's more likely that preference installation depends on
database schema modifications done by migration scripts than that
migration scripts depend on preferences in the database.

(Specifically, upcoming restructuring of how preferences are stored in
the database makes this very much the case.)
Support per-repository and per-filter preferences

Support different default settings per repository, and different user
overrides per repository and per filter.  Not all preferences can be set
per repository or filter; this is indicated by flags in the 'preferences'
table.  (Essentially this depends on whether the code that reads the
preference passes in the relevant repository or filter parameters, and
will be determined and implemented per setting.)

Also "modernize" the UI on /config.  Scrap the "Save Settings" button in
favor of automatic saving triggered by changes.

Also add support for editing system defaults and repository defaults,
available to users with the administrator role.

Also change how system default values are stored.  Instead of storing
those values in columns in the 'preferences' table, store them as rows in
the 'userpreferences' table with uid=NULL.  (The 'userpreferences' table's
name is by now quite inaccurate.)
Make commit.diff.rulerColumn configurable per repository
Make review.defaultOptOut configurable per repository and filter

Policy (also documented in the code):

If all of the user's filters that matched files in the review have
review.defaultOptOut enabled, then opt out.  When determining this, any
review filters of the user's that match files in the review count as
filters that don't have the review.defaultOptOut enabled.

If any of the user's filters that matched files in the review have
review.defaultOptOut disabled, then don't opt out.  When determining
this, review filters are ignored.

Otherwise, ignore the filter settings, and go with either the user's
per-repository or global setting (as set above.)