Implement abstraction over dependency contexts

Dependencies can be created between a file in the current project
and another file in the same project (internal dependency), a file
in another project (external dependency) or a binary file (binary
dependency). This is not subject to change.

Currently, dependencies can either be introduced by member reference
or by inheritance. However, this is subject to change, and in some
cases dependencies may be introduced by another relation (e.g.
dependencies introduced by a macro expansion).

Abstracting over dependency contexts makes it easier to add new
dependency contexts in sbt.