def find_next_unused_field_name(field_name, start_index, existing_collisions):
    """
    Finds a unused field name in the provided table starting with field_name.
    If field_name is not taken then it will be returned, if it is taken then the
    next name appended with an _X where X is a positive integer which is free will
    be returned.

    :param existing_collisions: A set of existing field names to skip over when finding
        the next free field name.
    :param start_index: The number to start looking for fields from.
    :param field_name: The field_name to find a unused name for.
    :return: A free field name starting with field_name possibly followed by an
        _X where X is a positive integer.
    """

    original_field_name = field_name
    i = start_index
    while True:
        field_name = f"{original_field_name}_{i}"
        i += 1
        if field_name not in existing_collisions:
            break
    return field_name, i