Another objectionable smilie.
Model Makeover: Post

* Delete old versions of the data model.
* Rename and Swiften AwfulPost -> Post.
* Add index on Post.postID.
* Add Post.lastModifiedDate and set it on insert.
* Rename Post.singleUserIndex -> filteredThreadIndex.
* Delete Post.editor and AwfulUser.editedPosts. (Nothing was using it.)
* Rename AwfulPostViewModel -> PostViewModel.
* Bits of formatting (mostly id -> instancetype).
Model Makeover: PrivateMessage

* AwfulPrivateMessage -> PrivateMessage.
* Add PrivateMessage.lastModifiedDate.
* Index PrivateMessage.messageID.
* Remove Awful- prefix from related classes.
* Formatting. (id -> instancetype and if ((self = [super init])) mostly.)
Model Makeover: ThreadTag

* AwfulThreadTag -> ThreadTag.
* Index ThreadTag.imageName and ThreadTag.threadTagID.
* Bit of NS_DESIGNATED_INITIALIZER.
Model Makeover: Thread

* AwfulThread -> Thread.
* Add index on Thread.threadID.
* Add Thread.lastModifiedDate and set it on insert.
* Split out AwfulStarCategory into its own header file.
* Thread.rating is now a float. Not sure why I thought a decimal was useful here.
* Promote Thread.numberOfVotes to Int32.
* Bit of id -> instancetype.
Model Makeover: User

* AwfulUser -> User.
* Add index to User.userID and to User.username.
* Remove User.idiotKing. authorClasses now covers this.
* User.lastPost -> User.lastPostDate.
* Add User.lastModifiedDate and set it on insert.
* De-prefix a couple related classes.
Model Makeover: ThreadFilter

* AwfulSingleUserThreadInfo -> ThreadFilter.
* Add compound index to ThreadFilter.{author,thread}.
Model Makeover: Forum

* AwfulForum -> Forum.
* Add index to Forum.forumID.
* Rename Forum.children -> childForums.
* Bunch of nearby id -> instancetype, NS_DESIGNATED_INITIALIZER, etc.
Model Makeover: ForumGroup

* AwfulCategory -> ForumGroup. (The Objective-C runtime exports a type called `Category`, so that name is unavailable.)
* Add index to ForumGroup.groupID.
* Forum.category -> Forum.group.

Bonus:
* Delete AwfulModels.h, as it's mostly empty now.
* Delete most of Prefix.pch and explicitly import what's needed.
Fix crashes restoring message view and message list controllers.
Hide image name in thread tag picker when the image is available.

It's usually covered up by the tag's image, but e.g. the "no filter" image has transparency.
Redo forums list in Swift, using composable data sources and a metadata entity.

I've been wanting to do the data sources like this for awhile, so I'm happy to get it going. The plan is to eventually switch all the table views over to the new system.

The forum tree is once again done entirely in Core Data. With a bit of prodding, the fetched results controller works great. The ForumMetadata attributes visibleInForumList and showsChildrenInForumList are used to keep track of which forums to show; two attributes are used so that e.g. if one expands every subforum in Games, then collapses Games, when one re-expands Games all the subforums are already expanded. The only downside is that, by fetching ForumMetadata, the fetched results controller don't pick up changes in forum names. Instead we need to do that ourselves.

I suspect that the AwfulForumTreeDataSource (i.e. the AwfulSettings-based one) had some extant issues so I'm not sad to see it go.

Favorite forums have also moved to ForumMetadata and are no longer stored in AwfulSettings. A one-time migration takes place after refreshing the forum list, which will probably happen quite quickly as the model changes will delete the cache.

There was some visual weirdness with rearranging the favorites rows, see comments in ForumListViewController.swift for more info.

The forums list has a refresh control now. I also switched the forums list to use the grouped style of table view as a superior way to stop the section headers from floating. Not sure if I like the all-caps headers though.

Favorite stars now disappear when editing to keep those cells a bit less cluttered. And the last row of each section now gets its separator hidden so there's no goofy little chunk of grey above the section headers.
Move and Swiften data store.

Since we're changing the model and skipping migration, I took the opportunity to move the data store class over to Swift and change the location of the store itself.

A directory is easier to keep track of than whatever detritus SQLite decides to leave behind, so let's just take over a whole directory. This greatly simplifies cleanup.

Speaking of cleanup, instead of moving old data stores into new positions, they're simply deleted. Migration would've failed anyway.

Now that user data (expanded and favorite forums) has returned to the Core Data store, it's no longer appropriate to leave it in the Caches directory. I've moved it to the Application Support folder and excluded it from backup.

Bonus:
* Document and property-ify NSFileManager category methods.
* Move the DataStore and NSManagedObjectContext category into the Models group, out of the unhelpfully-named "Data". The remaining files are set for obsolescence so I'm leaving them for now.
Update all entities' lastModifiedDate whenever the main managed object context is saved.

No longer any need to update it in awakeFromInsert.
Automatically prune the cache of week-old unused items.
Extract user profile into its own entity.

Then we can prune them from the cache independent of the User itself.

Bonus: AwfulProfileViewModel -> ProfileViewModel.
Fix Xcode 6.1.1-introduced compile errors.
Introduce and use AwfulObjectKey for inserting/updating managed objects.

This does us a couple favors:
1. Object keys make sure that we fully describe objects like User that might (temporarily) only have one of their two primary keys.
2. Object keys conform to NSCoding, making them handier for state preservation and restoration, and suitable for use as dictionary keys.

Also, thanks to AwfulObjectKey, we can generalize upserting from collections of keys and remove that responsibility from other code. This considerably simplifies some of the scraping code.

In addition, there was a bug preserving the state of a PM compose screen for a forwarded message, and there was a bug creating a newly-posted Thread object on the wrong context. They are fixed.
Header/import cleanup and formatting.

This was part of a failed attempt to split off the scraping stuff into its own framework. I was trying to figure out a build error "non-modular header inside framework module" and thought combing through headers might be handy. It wasn't, but there's no point wasting the effort.
Fix ScrapingTests for the Model Makeover.

:argh: "Unit tests written in Objective-C cannot import the Swift generated interfaces header ("$(PRODUCT_MODULE_NAME)-Swift.h") for application targets, and therefore cannot be used to test code that requires this header. (16931027)"

Bonus:
* Run the ScrapingTests inside the Awful app once more. We'll sub in a no-op app delegate to avoid pointless launching. This also means ScrapingTests don't need any CocoaPods, so delete that part too. (This is why ScrapingTests now link against Smilies.framework: it's currently where HTMLReader code sits.)
* Fix a couple of bugs from the Model Makeover.
* Move NSURL+QueryDictionary into Scraping folder and group. No point leaving it on its own when it's tested alongside scraping stuff.