def addOrUpdateNegotiator(self, protocol, config, constructorsByProtocol):
        """
        Adds or updates in the global registry the negotiator configuration
        identified by the protocol and contents of the negotiator configuration.

        Negotiator registry keys are a string of the format:
        protocol|username@host:port

        The username, host, and port values are expected in the config dict.

        This will also initialize fresh negotiator instances, if they are new/updated.

        @return: tuple with the negotiator key of the new or modified configuration
                 and a boolean which is True if the client was updated, False if was new, 
                 None if nothing happened (not new but no changes requiring update).
        """
        errorMsgs = ['The following configuration errors were found:\n']
        if not 'username' in config:
            errorMsgs.append('  A configuration for protocol %s is missing a username!' % protocol)
            self.logger.warning(errorMsgs[-1])
        elif not 'host' in config:
            errorMsgs.append('  A configuration for protocol %s is missing a host!' % protocol)
            self.logger.warning(errorMsgs[-1])
        elif not 'port' in config:
            errorMsgs.append('  A configuration for protocol %s is missing a port!' % protocol)
            self.logger.warning(errorMsgs[-1])
        
        negotiatorKey = self.buildNegotiatorKey(protocol, config)

        updated = self.hasNegotiator(negotiatorKey)
        added = not updated
        # make sure the updated config data is actually different
        if updated:
            updated = (self.getNegotiator(negotiatorKey).getConfig() != config)

        if updated:
            self.logger.debug('updating configuration for ' + negotiatorKey)
        elif added:
            self.logger.debug('adding configuration for ' + negotiatorKey)
        else:
            self.logger.debug('unchanged configuration for ' + negotiatorKey)

        # create negotiator instance
        # if updated config, disconnect old negotiator and create new
        if updated:
            self.removeNegotiator(negotiatorKey)
        self.negotiators[negotiatorKey] = constructorsByProtocol[protocol](negotiatorKey, config)

        # report errors, if any
        if len(errorMsgs) > 1:
            sublime.error_message(errorMsgs.join('\n'))
        return (negotiatorKey, updated)
dataset/ETHPy150Open nlloyd/SubliminalCollaborator/libs/sub_collab/registry.py/Registry.addOrUpdateNegotiator/original