API for retrieving/listing local charm files.
Created charmbrowser dispatcher method to support all of our urls. It does not yet support the view navigate
Added tests for charmbrowser dispatcher
Merge pull request #235 from hatched/charmbrowser-dispatcher

This branch now uses the new state object to render the charmbrowser urls.

#### Notes
This branch is blatantly missing tests for this new functionality.

#### To QA
Visit the following urls:
- /precise/apache2/:flags:/state/?text=apache2#related-charms ( should show the search results, charm details, and related-charms pane )
- /precise/apache2/:flags:/state/#related-charms ( should show the editorial results, charm details and the related-charms pane )
- /precise/apache2/:flags:/state/ ( should show the charm details )
- /:flags:/state/?text=apache2 ( should show the search results )
Merge pull request #234 from frankban/local-charm-files-api

This branch implements the basic API for retrieving/listing
local charm file contents from the Juju HTTPS endpoint.

Also changed the web handler so that xhr event subscribers
are no longer stored as an attribute.

This branch also includes some fixes clean up in the code
interactions between the environment object, the web handlers
and the fake backend.

Some tests have been reorganized.

Renamed web-handler and web-sandbox post methods:
`post` is now called `sendPostRequest`, so that consistency
is preserved between `sendPostRequest` and `sendGetRequest`,
given that `get` is already a base class method.

For all the reasons above the diff is long, sorry about that,
but they are mostly tests and I hope that word-based diff in 
Github will help reviewing some indentation changes.

QA:

For QAing, some code snippets must be executed in the
JavaScript console. I'll show them here, and they will be
referenced later:

Snippet 1:
```
app.env.listLocalCharmFiles(
    'local:precise/ghost-4', null,
    function(data) {
      console.log('status:', data.target.status);
      console.log('response:', data.target.responseText);
    }
);
```

Snippet 2:
```
app.env.listLocalCharmFiles(
    'local:precise/no-such', null,
    function(data) {
      console.log('status:', data.target.status);
      console.log('response:', data.target.responseText);
    }
);
```

Snippet 3:
```
app.env.getLocalCharmFileContents(
    'local:precise/ghost-4', 'hooks/install', null,
    function(data) {
      console.log('status:', data.target.status);
      console.log('response:', data.target.responseText);
    }
);
```

Snippet 4:
```
app.env.getLocalCharmFileContents(
    'local:precise/ghost-4', 'no-such-file', null,
    function(data) {
      console.log('status:', data.target.status);
    }
);
```

Sandbox QA:

- make devel
- open the JS console and define the following callback function:
  `var callback = function(data) {console.log(data)};`;
- ensure deploying local charms still work in sandbox mode, and 
  the default fallback icon is displayed in the service block and
  inspector header;
- deploy the local ghost charm;
- run Snippet 1: you should see a 200 status and a response
  with a JSON including an empty list of files;
- run Snippet 2: you should see a 400 status and a charm not found
  response;
- run snippet 4: it should return a 404.

Real env QA:
- juju quickstart an environment;
- switch to this branch and enable the JS console:
  `juju set juju-gui juju-gui-console-enabled=true juju-gui-source="https://github.com/frankban/juju-gui.git local-charm-files-api"`;
- wait for the GUI service to be ready, and then log in;
- ensure deploying local charms still works, and the charm own icons are
  properly displayed in the service block and inspector header;
- deploy the local ghost charm;
- run Snippet 1: you should see a 200 status and a response
  with a JSON including all the files in the ghost charm;
- run Snippet 2: you should see a 400 status and a charm not found
  response;
- run Snippet 3: you should see a 200 status and the hook's file
  contents;
- run snippet 4: it should return a 404.

Done. Sorry again for the long diff and QA, and thanks a lot!