Depcheck improvements

Improvements to dependency checking. Still a work in progress but ready for initial review and comments. cc @julen

    This allows a more decentralized approach to dependency checking where each
    module is responsible for its dependency checks.
    The non-core dependencies still need to be ported in a later commit.
    
    Note that this has a mild performance impact and this logic should only run
    once per instance startup.
I'd rather add the `required`, `optional` and `optimal` deps. as keys in `test_dependencies()` and avoid the `priority` thing altogether, otherwise everything is mixed and you'd need to transform the data in order to feed the templates. In other words, just generate the data the same way it's needed.

Something like:
```python
>> module.test_dependencies()
{
  'required': [dep1, dep2 ...depn],
  'optional': [dep1, dep2 ...depn],
  'optimal': [dep1, dep2 ...depn],
}
```
where each `dep` is a dictionary in the current format. No template changes needed.