Split assignment preprocessor into multiple preprocessors

This creates several smaller preprocessors from the original `AssignmentPreprocessor`:

* `IncludeHeaderFooter` -- appends cells from a header and/or footer notebook
* `TableOfContents` -- computes a table of contents from header cells, and puts it in the resources dictionary
* `RenderSolutions` -- replaces `ClearSolutions` and renders jinja templates either for a solution version or student version, and chooses cells selectively depending on whether they are for the solution version or student/release version.
* `ExtractTests` -- figures out which test cells go with which problem cells and extract the tests into the resources dictionary

I additionally created another app, `SolutionApp`, which provides `nbgrader solution` (similar to `nbgrader assign`). This way instructors can generate either a solution version of the notebook, or the assignment/release/student version of the notebook (we should probably pick a term for the two types of notebooks and be consistent with that terminology).

I know the `ExtractTests` preprocessor is probably going to have to change -- we still need to discuss that more -- but I didn't want to throw away the code for that just yet so I kept it in at least for reference.
This can simply be `if self.header`.