Merge this feature collection with another.

        Merges two feature collections using the given ``multiset_op``
        on each corresponding multiset and returns a new
        :class:`FeatureCollection`. The contents of the two original
        feature collections are not modified.

        For each feature name in both feature sets, if either feature
        collection being merged has a :class:`collections.Counter`
        instance as its value, then the two values are merged by
        calling `multiset_op` with both values as parameters.  If
        either feature collection has something other than a
        :class:`collections.Counter`, and `other_op` is not
        :const:`None`, then `other_op` is called with both values to
        merge them.  If `other_op` is :const:`None` and a feature
        is not present in either feature collection with a counter
        value, then the feature will not be present in the result.

        :param other: The feature collection to merge into ``self``.
        :type other: :class:`FeatureCollection`
        :param multiset_op: Function to merge two counters
        :type multiset_op: fun(Counter, Counter) -> Counter
        :param other_op: Function to merge two non-counters
        :type other_op: fun(object, object) -> object
        :rtype: :class:`FeatureCollection`

def merge_with(self, other, multiset_op, other_op=None):
        '''Merge this feature collection with another.

        Merges two feature collections using the given ``multiset_op``
        on each corresponding multiset and returns a new
        :class:`FeatureCollection`. The contents of the two original
        feature collections are not modified.

        For each feature name in both feature sets, if either feature
        collection being merged has a :class:`collections.Counter`
        instance as its value, then the two values are merged by
        calling `multiset_op` with both values as parameters.  If
        either feature collection has something other than a
        :class:`collections.Counter`, and `other_op` is not
        :const:`None`, then `other_op` is called with both values to
        merge them.  If `other_op` is :const:`None` and a feature
        is not present in either feature collection with a counter
        value, then the feature will not be present in the result.

        :param other: The feature collection to merge into ``self``.
        :type other: :class:`FeatureCollection`
        :param multiset_op: Function to merge two counters
        :type multiset_op: fun(Counter, Counter) -> Counter
        :param other_op: Function to merge two non-counters
        :type other_op: fun(object, object) -> object
        :rtype: :class:`FeatureCollection`

        '''
        result = FeatureCollection()
        for ms_name in set(self._counters()) | set(other._counters()):
            c1 = self.get(ms_name, None)
            c2 = other.get(ms_name, None)
            if c1 is None and c2 is not None:
                c1 = c2.__class__()
            if c2 is None and c1 is not None:
                c2 = c1.__class__()
            result[ms_name] = multiset_op(c1, c2)
        if other_op is not None:
            for o_name in (set(self._not_counters()) |
                           set(other._not_counters())):
                v = other_op(self.get(o_name, None), other.get(o_name, None))
                if v is not None:
                    result[o_name] = v
        return result