Fix bugs in required and excluded routes

It is now an error to specify more than one required route with the
same target (ValueError is raised).

It is now possible to define multiple excluded routes involving the
same target model.  Previously, the last defined exclusion route for
a target model would silently replace any other such routes.

The ModelTree `_required_routes` and `_excluded_routes` fields, which
used to be dicts keyed on target model, are now dicts keyed on
(source, target) tuple, and the value of the dict is the join field, or None
if there is no join field specified.  `_required_join_fields` and
`_excluded_join_fields` are no longer needed.  The code is simpler, but
lookup of a target in the excluded routes dict is less efficient now.
I expect that doesn't matter much, but if it does, we can change
to keying on target, with the value being a list of source:field tuples.

Signed-off-by: Kevin Murphy <murphyke@email.chop.edu>
Meaning:

    """
    Routes ...

?  That's certainly my preference, although I changed when I noticed that the official Python docs all use this convention:

    """Strangely ugly and dissatisfying comment
    
    Blah blah
    """"

I also really like always using triple quotes even even for one-liners, although they steal precious characters