docs: def group_join(self, inner_iterable, outer_key_selector=identity, inner_key_selector=identity,
               result_selector=lambda outer, grouping: grouping):
          '''Match elements of two sequences using keys and group the results.
  
          The group_join() query produces a hierarchical result, with all of the
          inner elements in the result grouped against the matching outer
          element.
  
          The order of elements from outer is maintained. For each of these the
          order of elements from inner is also preserved.
  
          Note: This method uses deferred execution.
  
          Args:
              inner_iterable: The sequence to join with the outer sequence.
  
              outer_key_selector: An optional unary function to extract keys from
                  elements of the outer (source) sequence. The first positional
                  argument of the function should accept outer elements and the
                  result value should be the key. If omitted, the identity
                  function is used.
  
              inner_key_selector: An optional  unary function to extract keys
                  from elements of the inner_iterable. The first positional
                  argument of the function should accept outer elements and the
                  result value should be the key.  If omitted, the identity
                  function is used.
  
              result_selector: An optional binary function to create a result
                  element from an outer element and the Grouping of matching
                  inner elements. The first positional argument is the outer
                  elements and the second in the Grouping of inner elements
                  which match the outer element according to the key selectors
                  used. If omitted, the result elements will be the Groupings
                  directly.
  
          Returns:
              A Queryable over a sequence with one element for each group in the
              result as returned by the result_selector. If the default result
              selector is used, the result is a sequence of Grouping objects.
  
          Raises:
              ValueError: If the Queryable has been closed.
              TypeError: If the inner_iterable is not in fact iterable.
              TypeError: If the outer_key_selector is not callable.
              TypeError: If the inner_key_selector is not callable.
              TypeError: If the result_selector is not callable.
          '''
          if self.closed():
              raise ValueError("Attempt to call group_join() on a closed Queryable.")
  
          if not is_iterable(inner_iterable):
              raise TypeError("Cannot compute group_join() with inner_iterable of non-iterable {type}".format(
                      type=str(type(inner_iterable))[7: -1]))
  
          if not is_callable(outer_key_selector):
              raise TypeError("group_join() parameter outer_key_selector={outer_key_selector} is not callable".format(
                      outer_key_selector=repr(outer_key_selector)))
  
          if not is_callable(inner_key_selector):
              raise TypeError("group_join() parameter inner_key_selector={inner_key_selector} is not callable".format(
                      inner_key_selector=repr(inner_key_selector)))
  
          if not is_callable(result_selector):
              raise TypeError("group_join() parameter result_selector={result_selector} is not callable".format(
                      result_selector=repr(result_selector)))
  
          return self._create(self._generate_group_join_result(inner_iterable, outer_key_selector,
                                                         inner_key_selector, result_selector))