Move message and conversation storage to IndexedDB

Getting up and running with IndexedDB was pretty easy, thanks to
backbone. The tricky part was making reads and writes asynchronous.
In that process I did some refactoring on Whisper.Threads, which
has been renamed Conversations for consistency with the view names.

This change also adds the unlimitedStorage permission.
Save incoming messages and pass to frontend asynchronously

After a message is saved asynchronsly, fire an event and pass the
message attributes to frontend listeners via the chrome-runtime API.

This behavior is similar to the 'storage' event fired by localStorage.
Consolidate message callbacks

Register the runtime callback at the top level view rather than having
each conversation view register independently.
Also refactors Layout into InboxView.
Destroy all globals

Well, not *all* globals..
Fix scroll when re-opening a conversation
Get rid of Layout global

Instead, trigger and listen for events on the conversation collection
object.
Fix tests
Store attachments as binary blobs

Move base64 encoding of attachments to an AttachmentView. This makes
image rendering an asynchronous task so we fire an update event to
indicate to the parent MessageListView that its content has changed
height and it is time to scroll down.
Rebind events when opening a previously opened conversation