[SCHEMA] Support a full-featured tag interface, part 1.

Summary:
This is the first in a series of three or four commits.

Rename UserTag to Tag, and tweak its schema, as well as the Folder schema.
Everything we expose as a tag now has a corresponding Tag row, whether the tag
comes from an IMAP folder ('gmail-jobslist'), was created via the API
('my-awesome-tag'), or has some special semantics ('unread', 'drafts', ...).
This makes it a lot easier to reason about what's going on.

This is a precursor to the following changes:
 - Modify our actions code such that Thread.folders is *always* an exact mirror
   of what we sync from the IMAP backend. We express local actions only by
   mutating tags, not folders. Again, this makes things simpler.

 - Get rid of the Redis queue for actions syncback. Instead, we'll have a
   syncback service that consumes the transaction log, and executes actions
   based on recorded tag mutations. Per discussion with mg, this means that,
   for example, the API server can run on a machine without access to user
   credentials.

Test Plan: Will add some tests once I put all the pieces together.

Reviewers: spang

Differential Revision: https://review.inboxapp.com/D159
Tag interface part 2: Better record added/removed tags in the tx log

Summary:
Added or removed tags now appear in the transaction log as revisions of the
Thread object.

[Stop reading here if you don't care about implementation details.]

Given related parent and child tables, we add the ability to record updates to
a parent's collection of children as a revision of the parent. See the
docstring in models/revision.py for details.

(Why not just have the TagItems association table subclass HasRevisions? you
may ask. Good question. One reason is that handling removed tags that way is
tricky, because all the transaction log can tell you is that a TagItem with
some ID was deleted. But you can't figure out from that what the corresponding
tag or thread was. Another reason is that delete transactions for the TagItem
table aren't created at all if you use an association proxy
(`thread.tags.remove(tag)`), because in this case sqlalchemy directly issues
sql to the database, without instantiating the association object.

Test Plan: Still working on the tests.

Reviewers: spang

Differential Revision: https://review.inboxapp.com/D160
Tag interface, part 3.

Summary:
 * Delete local actions code. Local actions are now expressed solely by
   adding/removing tags. Refactor the rest of the existing actions code as a
   result.

 * Add a listener service which checks the transaction log for tag mutations,
   and executes the corresponding syncback actions.

 * Expose 'unread' and 'archive' as tags on threads.

 * Support dependent tag mutations (e.g., remove the 'inbox' tag when you add
   the 'archive' tag, and vice versa).

Test Plan: Working on it.

Reviewers: spang

Differential Revision: https://review.inboxapp.com/D162
[SCHEMA][WIP] Client sync API, version 1.

This is a kind of hacky sketch implementation, which only returns changes for
message and thread objects.

Still need to:
 * Refactor and clarify revision code.
 * Support sync for other object types (contacts, drafts, attachments, tags, ...).
 * Parse an optional 'type' parameter on the /sync/events API call, to allow
   clients to only fetch changes on object types that they care about.
 * Return only deltas on object updates, not full object copies.