def reinsertList(lst,selection,insert_row,current_index=0):

    """
    Generic implementation for reinserting a set of elements.

    lst : a list of items (data type not important)
    selection : list/set of indices of elements in lst
    insert_row : an integer index into lst
    current_index : index of the current song, optional

    returns the new list, actual insert row, number of selected items
    and the updated current index.

    selects the set of items in selection in the order in which
    they appear in lst. These items are then insert at insert_row.
    removal / insertion may change the actual index of
    insert_row and current_index so these values will be recalculated
    accordingly
    """
    lsta = []
    lstb = []
    idx = 0;
    insert_offset = 0; # for updating current idx
    new_index = -1;

    for item in lst:
        if idx in selection:
            # if we need to update the current idx after drop
            if idx == current_index:
                insert_offset = len(lstb)
            # if the selection effects insert row
            if idx < insert_row:
                insert_row -= 1
            lstb.append(item)
        else:
            if (idx == current_index):
                new_index = len(lsta)
            lsta.append(item)
        idx += 1;

    # insert row must be in range 0..len(lsta)
    insert_row = min(insert_row, len(lsta))
    if new_index < 0:
        new_index = insert_row + insert_offset;
    elif insert_row <= new_index:
        new_index += len(lstb)

    if insert_row < len(lsta):
        lsta = lsta[:insert_row] + lstb + lsta[insert_row:]
    else:
        lsta = lsta + lstb

    return (lsta, insert_row, insert_row+len(lstb), new_index)