'Add a cmdset to the handler, on top of the old ones, unless it
is set as the default one (it will then end up at the bottom of the stack)
Args:
cmdset (CmdSet or str): Can be a cmdset object or the python path
to such an object.
emit_to_obj (Object, optional): An object to receive error messages.
permanent (bool, optional): This cmdset will remain across a server reboot.
default_cmdset (Cmdset, optional): Insert this to replace the
default cmdset position (there is only one such position,
always at the bottom of the stack).
Notes:
An interesting feature of this method is if you were to send
it an *already instantiated cmdset* (i.e. not a class), the
current cmdsethandler\'s obj attribute will then *not* be
transferred over to this already instantiated set (this is
because it might be used elsewhere and can cause strange
effects).  This means you could in principle have the
handler launch command sets tied to a *different* object
than the handler. Not sure when this would be useful, but
it\'s a \'quirk\' that has to be documented.'

def add(self, cmdset, emit_to_obj=None, permanent=False, default_cmdset=False):

    if (not (isinstance(cmdset, basestring) or utils.inherits_from(cmdset, CmdSet))):
        string = _('Only    CmdSets    can    be    added    to    the    cmdsethandler!')
        raise Exception(string)
    if callable(cmdset):
        cmdset = cmdset(self.obj)
    elif isinstance(cmdset, basestring):
        cmdset = self._import_cmdset(cmdset)
    if (cmdset and (cmdset.key != '_CMDSET_ERROR')):
        cmdset.permanent = permanent
        if (permanent and (cmdset.key != '_CMDSET_ERROR')):
            storage = (self.obj.cmdset_storage or [''])
            if default_cmdset:
                storage[0] = cmdset.path
            else:
                storage.append(cmdset.path)
            self.obj.cmdset_storage = storage
        if default_cmdset:
            self.cmdset_stack[0] = cmdset
        else:
            self.cmdset_stack.append(cmdset)
        self.update()
