<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def selection_changed(self, index, source, update, commentbrowser, mapper):
 """Callback for when the asset or shot browser changed its selection :param index: the modelindex with the descriptor tree item as internal data :type index: QtCore.QModelIndex :param source: the shot or asset browser to that changed its selection :type source: :class:`jukeboxcore.gui.widgets.browser.AbstractTreeBrowser` :param update: the browser to update :type update: :class:`jukeboxcore.gui.widgets.browser.AbstractTreeBrowser` :param browser: the comment browser to update :type browser: :class:`jukeboxcore.gui.widgets.browser.AbstractTreeBrowser` :param mapper: the data widget mapper to update :type mapper: :class:`QtGui.QDataWidgetMapper` :returns: None :rtype: None :raises: None """

        if not index.isValid():  # no descriptor selected
            self.update_version_descriptor(None, None, None, update, commentbrowser)
            self.set_info_mapper_model(mapper, None)
            return

        descitem  = index.internalPointer()
        descriptor = descitem.internal_data()[0]
        taskdata = source.selected_indexes(2)[0].internalPointer()
        task = taskdata.internal_data()
        releasetype = self.get_releasetype()
        self.update_version_descriptor(task, releasetype, descriptor, update, commentbrowser)

        self.set_info_mapper_model(mapper, update.model)
        sel = update.selected_indexes(0)
        if sel:
            self.set_mapper_index(sel[0], mapper)