Returns true if both buildrequest can be merged, via Deferred.

        This implements Buildbot's default collapse strategy.

def canBeCollapsed(master, br1, br2):
        """
        Returns true if both buildrequest can be merged, via Deferred.

        This implements Buildbot's default collapse strategy.
        """
        # short-circuit: if these are for the same buildset, collapse away
        if br1['buildsetid'] == br2['buildsetid']:
            return True

        # get the buidlsets for each buildrequest
        selfBuildsets = yield master.data.get(
            ('buildsets', str(br1['buildsetid'])))
        otherBuildsets = yield master.data.get(
            ('buildsets', str(br2['buildsetid'])))

        # extract sourcestamps, as dictionaries by codebase
        selfSources = dict((ss['codebase'], ss)
                           for ss in selfBuildsets['sourcestamps'])
        otherSources = dict((ss['codebase'], ss)
                            for ss in otherBuildsets['sourcestamps'])

        # if the sets of codebases do not match, we can't collapse
        if set(selfSources) != set(otherSources):
            return False

        for c, selfSS in selfSources.items():
            otherSS = otherSources[c]
            if selfSS['repository'] != otherSS['repository']:
                return False

            if selfSS['branch'] != otherSS['branch']:
                return False

            if selfSS['project'] != otherSS['project']:
                return False

            # anything with a patch won't be collapsed
            if selfSS['patch'] or otherSS['patch']:
                return False
            # get changes & compare
            selfChanges = yield master.data.get(('sourcestamps', selfSS['ssid'], 'changes'))
            otherChanges = yield master.data.get(('sourcestamps', otherSS['ssid'], 'changes'))
            # if both have changes, proceed, else fail - if no changes check revision instead
            if selfChanges and otherChanges:
                continue
            elif selfChanges and not otherChanges:
                return False

            elif not selfChanges and otherChanges:
                return False

            # else check revisions
            elif selfSS['revision'] != otherSS['revision']:
                return False

        return True