def uri_split_tree(uri):
    """
    Return (scheme, (user, passwd, host, port), path,
               ((k1, v1), (k2, v2), ...), fragment) using
    basic_urisplit(), then split_authority() and split_query() on the
    result.

    >>> uri_split_tree(
    ...     'http://%42%20+blabla:lol@%77ww.foobar.org/%7Exilun/' +
    ...     '?query=+++%2b&=&===&a=b&&&+++aaa%3D=+%2B%2D&&&&' +
    ...     '#frag+++%42')
    ('http', ('%42%20+blabla', 'lol', '%77ww.foobar.org', None), '/%7Exilun/', (('query', '+++%2b'), ('', ''), ('', '=='), ('a', 'b'), ('+++aaa%3D', '+%2B%2D')), 'frag+++%42')
    """
    scheme, authority, path, query, fragment = basic_urisplit(uri)
    if authority:
        authority = split_authority(authority)
    if query:
        query = split_query(query)
    return (scheme and scheme or None, authority and authority or None,
            path and path or None, query and query or None,
            fragment and fragment or None)