'Update the map of partition => [replicas] to be reassigned from
insufficiently-far-apart replicas.'

def _gather_parts_for_dispersion(self, assign_parts, replica_plan):

    for part in range(self.parts):
        if (not self._can_part_move(part)):
            continue
        replicas_at_tier = defaultdict(int)
        for dev in self._devs_for_part(part):
            for tier in dev['tiers']:
                replicas_at_tier[tier] += 1
        undispersed_dev_replicas = []
        for replica in self._replicas_for_part(part):
            dev_id = self._replica2part2dev[replica][part]
            if (dev_id == NONE_DEV):
                continue
            dev = self.devs[dev_id]
            if all(((replicas_at_tier[tier] <= replica_plan[tier]['max']) for tier in dev['tiers'])):
                continue
            undispersed_dev_replicas.append((dev, replica))
        if (not undispersed_dev_replicas):
            continue
        undispersed_dev_replicas.sort(key=(lambda dr: dr[0]['parts_wanted']))
        for (dev, replica) in undispersed_dev_replicas:
            if ((not self._can_part_move(part)) and (not (replicas_at_tier[dev['tiers'][(-1)]] > 1))):
                continue
            dev['parts_wanted'] += 1
            dev['parts'] -= 1
            assign_parts[part].append(replica)
            self.logger.debug('Gathered    %d/%d    from    dev    %s    [dispersion]', part, replica, pretty_dev(dev))
            self._replica2part2dev[replica][part] = NONE_DEV
            for tier in dev['tiers']:
                replicas_at_tier[tier] -= 1
            self._set_part_moved(part)
