'Perform a widening between self and other states
:param others:
:return:'

def widen(self, *others):

    if (len(set((frozenset(o.plugins.keys()) for o in others))) != 1):
        raise SimMergeError('Unable    to    widen    due    to    different    sets    of    plugins.')
    if (len(set((o.arch.name for o in others))) != 1):
        raise SimMergeError('Unable    to    widen    due    to    different    architectures.')
    widened = self.copy()
    widening_occurred = False
    for p in self.plugins:
        if (p in ('solver_engine', 'unicorn')):
            continue
        plugin_state_widened = widened.plugins[p].widen([_.plugins[p] for _ in others])
        if plugin_state_widened:
            l.debug('Widening    occured    in    %s', p)
            widening_occurred = True
    return (widened, widening_occurred)
