This function calls a json_json method, if the type has one, otherwise
    calls back into to_json().  It also check whether the method takes an
    'extraneous' argument and passes that through if possible.

def _json_data(x, extraneous):
    """This function calls a json_json method, if the type has one, otherwise
    calls back into to_json().  It also check whether the method takes an
    'extraneous' argument and passes that through if possible."""

    if type(x) in has_json_data and has_json_data[type(x)]:
        if json_data_takes_extraneous[type(x)]:
            return x.json_data(extraneous=extraneous)
        else:
            return x.json_data()
    else:
        htj = hasattr(x, "json_data") and callable(x.json_data)
        has_json_data[type(x)] = htj
        if htj:
            argspec = inspect.getargspec(x.json_data)
            tjte = 'extraneous' in argspec.args or argspec.keywords
            json_data_takes_extraneous[type(x)] = tjte
            if tjte:
                return x.json_data(extraneous=extraneous)
            else:
                return x.json_data()
        else:
            return to_json(x, extraneous)