'Arrange the tabs in rows, in the order in which they were added.
If n_rows >= 1, this will be the number of rows used. Otherwise the
number of rows will be calculated according to the number of tabs and
max_tabs_per_row. In this case, the number of rows may change when
adding/removing tabs.'

def _arrange_tabs(self):

    for tab_name in self._tabs.keys():
        self._tabs.pop(tab_name).destroy()
    self._reset_tab_rows()
    if (not self._tab_names):
        return
    else:
        if ((self.n_rows is not None) and (self.n_rows > 0)):
            n_rows = self.n_rows
        else:
            n_rows = (((len(self._tab_names) - 1) // self.max_tabs_per_row) + 1)
        expand_tabs = (self.expand_tabs or (n_rows > 1))
        i = 0
        for row_index in xrange(n_rows):
            n_tabs = ((((len(self._tab_names) - i) - 1) // (n_rows - row_index)) + 1)
            tab_names = self._tab_names[i:(i + n_tabs)]
            i += n_tabs
            self._add_tab_row(tab_names, expand_tabs)
        selected = self._selected_tab
        self.set_selected_tab(None)
        if (selected in self._tab_names):
            self.set_selected_tab(selected)
        return
