Prompt for a value
                                        .                    .
    :param question:                    Question to be asked
    :param choices:                     List of authorized answers
    :param default:                     Value suggested by default
    :param display_choices:             Display accepted choices
    :param display_indices:             Display the indice in the list next to the choice
    :param authorize_list:              Set to true if a list of answers may be accepted
    :param is_question:                 Set to true to append a question mark
    :param no_confirm:                  Set to true to not prompt for a confirmation of the value
    :param required:                    Set to false if an empty answer is authorized
    :param regex:                       TODO
    :param regex_format                 TODO
    :param max_laps:                    Exit after N laps
    :param input:                       Used for unit testing

    :return:

def prompt_4_value(question, choices = None, default = None, display_choices = True, display_indices = False, authorize_list = False, is_question = False, no_confirm = False, required = True, regex = None, regex_format = '', max_laps = 5, input = None, return_index = False):
    """
    Prompt for a value
                                        .                    .
    :param question:                    Question to be asked
    :param choices:                     List of authorized answers
    :param default:                     Value suggested by default
    :param display_choices:             Display accepted choices
    :param display_indices:             Display the indice in the list next to the choice
    :param authorize_list:              Set to true if a list of answers may be accepted
    :param is_question:                 Set to true to append a question mark
    :param no_confirm:                  Set to true to not prompt for a confirmation of the value
    :param required:                    Set to false if an empty answer is authorized
    :param regex:                       TODO
    :param regex_format                 TODO
    :param max_laps:                    Exit after N laps
    :param input:                       Used for unit testing

    :return:
    """
    if choices and display_choices and not display_indices:
        question = question + ' (' + '/'.join(choices) + ')'
    lap_n = 0
    while True:
        if lap_n >= max_laps:
            printError('Automatically abording prompt loop after 5 failures')
            return None
        lap_n += 1
        can_return = False
        # Display the question, choices, and prompt for the answer
        if is_question:
            question = question + '? '
        printError(question)
        if choices and display_indices:
            for c in choices:
                printError('%3d. %s' % (choices.index(c), c))
            printError('Enter the number corresponding to your choice: ', False)
        choice = prompt(input)
        # Set the default value if empty choice
        if not choice or choice == '':
            if default:
                if no_confirm or prompt_4_yes_no('Use the default value (' + default + ')'):
                    #return default
                    choice = default
                    can_return = True
            elif not required:
                can_return = True
            else:
                printError('Error: you cannot leave this parameter empty.')
        # Validate the value against a whitelist of choices
        elif choices:
            user_choices = [item.strip() for item in choice.split(',')]
            if not authorize_list and len(user_choices) > 1:
                printError('Error: multiple values are not supported; please enter a single value.')
            else:
                choice_valid = True
                if display_indices and int(choice) < len(choices):
                    int_choice = choice
                    choice = choices[int(choice)]
                else:
                    for c in user_choices:
                        if not c in choices:
                            printError('Invalid value (%s).' % c)
                            choice_valid = False
                            break
                if choice_valid:
                    can_return = True
        # Validate against a regex
        elif regex:
            if regex.match(choice):
                #return choice
                can_return = True
            else:
                printError('Error: expected format is: %s' % regex_format)
        else:
            # No automated validation, can attempt to return
            can_return = True
        if can_return:
            # Manually onfirm that the entered value is correct if needed
            if no_confirm or prompt_4_yes_no('You entered "' + choice + '". Is that correct', input=input):
                return int(int_choice) if return_index else choice