def METHOD_NAME(params, main_func, matching_mode, input_nesting, outputs_num):
    '''params will spread using the matching fmode,
       the main_func is the function to apply
       the input_nesting should be like an Integer List like [1, 2, 1, 3...] one level per parameter
       outputs_num: number of outputs (Integer)
       '''
    input_levels = [levels_of_list_or_np(p) for p in params]
    over_levels = [lv > dl for lv, dl in zip(input_levels, input_nesting)]
    one_output = outputs_num == 1
    matching_f = list_match_func[matching_mode]
    if one_output:
        result = []
    else:
        result = [[] for l in range(outputs_num)]
    if any(over_levels):
        p_temp = []
        for p, lv, dl in zip(params, input_levels, input_nesting):
            if lv <= dl:
                p_temp.append([p])
            else:
                p_temp.append(p)
        params = matching_f(p_temp)
        for g in zip(*params):
            local_result = METHOD_NAME(g, main_func, matching_mode, input_nesting, outputs_num)
            append_result(result, local_result, one_output)
    else:
        result = main_func(matching_f(params))
    return result