def from_array_list(required_type, result, list_level, is_builtin):
    """
    Tries to parse the `result` as type given in `required_type`, while traversing into lists as often as specified in `list_level`.

    :param required_type: What it should be parsed as
    :type  required_type: class

    :param result: The result to parse

    :param list_level: "list of" * list_level
    :type  list_level: int

    :param is_builtin: if it is a builtin python type like :class:`int`, :class:`bool`, etc.
    :type  is_builtin: bool

    :return: the result as `required_type` type
    """
    logger.debug("Trying parsing as {type}, list_level={list_level}, is_builtin={is_builtin}".format(
        type=required_type.__name__, list_level=list_level, is_builtin=is_builtin
    ))
    if list_level > 0:
        assert isinstance(result, (list, tuple))
        return [from_array_list(required_type, obj, list_level-1, is_builtin) for obj in result]
    # end if
    if is_builtin:
        if isinstance(result, required_type):
            logger.debug("Already is correct type.")
            return required_type(result)
        elif isinstance(required_type, unicode_type):  # handle str, so emojis work for py2.
            return u(result)
        else:
            import ast
            logger.warn("Trying parsing with ast.literal_eval()...")
            return ast.literal_eval(str(result))  # raises ValueError if it could not parse
        # end if
    else:
        return required_type.from_array(result)