Multi-dir webservice design

## Multi-directory support

THIS IS CURRENTLY BROKEN  for some nbmanager refactoring. -[Zsailer](https://github.com/Zsailer)

This PR is a web-service redesign for the notebook that allows multi-directory navigation. This was proposed in [IPEP 16](https://github.com/ipython/ipython/wiki/IPEP-16%3A-Notebook-multi-directory-dashboard-and-URL-mapping) and will not be released in 1.0. 

THIS DOES NOT include UI for the multi-directory support. All front-end changes will be made in a separate PR. If you are interested in a simple user-interface to navigate through your file-system, checkout this [branch.](https://github.com/Zsailer/ipython/tree/multidir-UI)

#### Things that have changed:

* The notebooks are not longer identified by a UUID. 
* The URL includes the path to the notebook and the names of opened notebooks
* New webservice APIs are introduced... 'sessions', 'notebooks', 'kernels', and 'contents' (not quite finished).
* A new mapping manager, called a ```session```, is used to link notebooks and kernels... kernels are not longer entangled with the notebook_id
* User can navigate through sub-directories by adding the files in the URL 'path'.
* The JSON structures sent between client and server are cleaned up and follow a Github style model.
* The "new" and "copy" actions in the notebook no longer have their own URL. They use a POST request to the server.
* Notebook rename is no longer broken, and will not overwrite other files.

I also created a short talk and repo, demo-ing the new service in a few notebooks. Check it out [here.](https://github.com/Zsailer/multidir_ipynb_tutorial)

## Not ready to be merged
Things to do:

### Services

- [ ] Make sure that we are consistent and logical about using leading "/" in our URL patterns
- [ ] Make sure that trailing slashes are not used for collections - update this in the IPEP
- [x] Make sure that all handler methods in all service use the `json_errors` decorator and write tests for this.

### Kernels

#### handlers.py

- [x] Use the `json_errors` decorator on all handler method to return proper JSON errors. 

#### test_kernels_api.py

- [x] In test_main_kernel_handler use mkkernel to create 2 kernels and assert that there are two in the list of dicts.
- [x] In test_kernel_handler do self.assertIn('ws_url', r.json())
- [x] In test_kernel_handler assign data = r.json()
- [x] In all test methods, check success status code
- [x] Add tests to see what happends when there is a request against an invalid id.
- [x] Test all handler methods to make sure proper JSON errors are sent.

### Notebooks

- [ ] Web service collections should not use a trailing slash. This is to follow GitHub's conventions, so it is /api/notebooks, not /api/notebooks/. This will allow us to remove `NotebookRootHandler`.
- [ ] `NotebookHandler`.get
- [ ] Direct .ipynb download in web app to the `/files` URL.
- [ ] Make sure that the `files` handler set the `Content-Type` to `application/json` if the filename ends with `.ipynb`. It should also set the `Content-Disposition`.
- [ ] Test the hell out of `named_notebook_path` for garbage paths and make sure the right errors are sent back
- [ ] How on earth do we want to handle notebook copies?
- [ ] Remove the .py upload and download from the web application
- [ ] Test notebook uploading interactively and make sure `.py` files can't be uploaded
- [ ] Test notebook checkpoints interactively

#### handlers.py
- [ ] Test all handler methods to make sure that they send back proper JSON errors messages and status codes. We should try to call all methods in every bad way possible to test the different exceptions that can be raised.
- [ ] Test the value of the `Location` header by doing a GET request against it and making sure the expected model is returned.
- [ ] Write proper docstrings for everything.

#### nbmanager.py

- [ ] Write proper docstrings for everything.
- [ ] Write a test for `copy_notebook`.

#### filenbmanager.py

- [ ] Make sure notebooks is older formats can be uploaded. To do this, we need to create a `convert_to_current` function in `nbformat. current`. We then need to call this function on any notebook JSON (just the content) before saving it to disk. - [] Extract this logic from `current.reads_json` and have `reads_json` call the new function. This is currently at L185.

#### checkpoints

- [ ] Write tests for checkpoints web service.
- [ ] Make sure that the checkpoints model is consistent with our other other models.
- [ ] In the checkpoint model rename `checkpoint_id` to id. This will also have to be changed in the web app JavaScript code.


### Sessions

#### handlers.py

- [ ] Test `Location` header in the `POST` call.

#### sessionmanager.py

- [ ] Update docstrings