Tries to merge all possible combinations of entities.

    This tries to merge every entity in the old schedule with every entity in
    the new schedule. Unlike _MergeSameId, the ids do not need to match.
    However, _MergeDifferentId is much slower than _MergeSameId.

    This method makes use of various methods like _Merge and _Migrate which
    are not implemented in the abstract DataSetMerger class. These method
    should be overwritten in a subclass to allow _MergeSameId to work with
    different entity types.

    Returns:
      The number of merged entities.

def _MergeDifferentId(self):
    """Tries to merge all possible combinations of entities.

    This tries to merge every entity in the old schedule with every entity in
    the new schedule. Unlike _MergeSameId, the ids do not need to match.
    However, _MergeDifferentId is much slower than _MergeSameId.

    This method makes use of various methods like _Merge and _Migrate which
    are not implemented in the abstract DataSetMerger class. These method
    should be overwritten in a subclass to allow _MergeSameId to work with
    different entity types.

    Returns:
      The number of merged entities.
    """
    # TODO: The same entity from A could merge with multiple from B.
    # This should either generate an error or should be prevented from
    # happening.
    for a in self._GetIter(self.feed_merger.a_schedule):
      for b in self._GetIter(self.feed_merger.b_schedule):
        try:
          self._Add(a, b, self._MergeEntities(a, b))
          self._num_merged += 1
        except MergeError:
          continue

    for a in self._GetIter(self.feed_merger.a_schedule):
      if a not in self.feed_merger.a_merge_map:
        self._num_not_merged_a += 1
        newid = self._HasId(self.feed_merger.b_schedule, self._GetId(a))
        self._Add(a, None,
                  self._Migrate(a, self.feed_merger.a_schedule, newid))
    for b in self._GetIter(self.feed_merger.b_schedule):
      if b not in self.feed_merger.b_merge_map:
        self._num_not_merged_b += 1
        newid = self._HasId(self.feed_merger.a_schedule, self._GetId(b))
        self._Add(None, b,
                  self._Migrate(b, self.feed_merger.b_schedule, newid))

    return self._num_merged