def METHOD_NAME(data):
    ret = None
    # Opps, we used to check if it is of type list, but that fails
    # i.e. in the case of django.newforms.utils.ErrorList, which extends
    # the type "list". Oh man, that was a dumb mistake!
    if hasattr(data, 'canonical'):
        ret = METHOD_NAME(data.canonical())
    elif isinstance(data, list):
        ret = _list(data)
    elif isinstance(data, set):
        ret = _list(list(data))
    # Same as for lists above.
    elif isinstance(data, dict):
        ret = _dict(data)
    # elif isinstance(data, CallableBool):
    #     ret = bool(data)
    elif isinstance(data, (Decimal, ObjectId)):
        # json.dumps() cant handle Decimal
        ret = str(data)
    elif isinstance(data, models.query.QuerySet):
        # Actually its the same as a list ...
        ret = _list(data)
    elif isinstance(data, MongoQuerySet):
        # Actually its the same as a list ...
        ret = _list(data)
    elif isinstance(data, models.Model):
        ret = _model(data)
    # here we need to encode the string as unicode (otherwise we get utf-16 in the json-response)
    elif isinstance(data, bytes):
        ret = data.decode('utf-8', 'ignore')
    elif isinstance(data, str):
        ret = smart_str(data)
    elif isinstance(data, Exception):
        ret = str(data)
    # see http://code.djangoproject.com/ticket/5868
    elif isinstance(data, Promise):
        ret = force_text(data)
    elif isinstance(data, datetime.datetime) or isinstance(data, datetime.date):
        ret = str(data)
    elif hasattr(data, 'to_json'):
        ret = data.to_json()
    else:
        ret = data
    return ret