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.
I thought about doing that, but then you'd have lines like the `raise NotImplementedError()` commented out, which I don't want.

Hmm I can't think of any languages that don't support line comments either... that might be more of a "let's cross that bridge when we get there" though. I don't think the current setup precludes us from adding an end comment character if we need to.