def traverse_many(self, attribute, source_sequence, target_sequence,
                      visitor):
        """
        Traverses the given source and target sequences and makes appropriate
        calls to :method:`traverse_one`.

        Algorithm:
        1) Build a map target item ID -> target data item from the target
           sequence;
        2) For each source data item in the source sequence check if it
           has a not-None ID; if yes, remove the corresponding target from the
           map generated in step 1) and use as target data item for the
           source data item; if no, use `None` as target data item;
        3) For the remaining items in the target map from 1), call
           :method:`traverse_one` passing `None` as source (REMOVE);
        4) For all source/target data item pairs generated in 2, call
           :method:`traverse_one` (ADD or UPDATE depending on whether target
           item is `None`).

        :param source_sequence: iterable of source data proxies
        :type source_sequence: iterator yielding instances of
                               `DataTraversalProxy` or None
        :param target_sequence: iterable of target data proxies
        :type target_sequence: iterator yielding instances of
                               `DataTraversalProxy` or None
        """
        target_map = {}
        if not target_sequence is None:
            for target in target_sequence:
                target_map[target.get_id()] = target
        src_tgt_pairs = []
        if not source_sequence is None:
            for source in source_sequence:
                source_id = source.get_id()
                if not source_id is None:
                    # Check if target exists for UPDATE.
                    target = target_map.pop(source_id, None)
                else:
                    # Source is new, there is no target, so ADD.
                    target = None
                src_tgt_pairs.append((source, target))
        # All targets that are now still in the map where not present in the
        # source and therefore need to be REMOVEd.
        for target in itervalues_(target_map):
            if not (None, target) in self.__trv_path:
                self.traverse_one(attribute, None, target, visitor)
        #
        for source, target in src_tgt_pairs:
            if not (source, target) in self.__trv_path:
                self.traverse_one(attribute, source, target, visitor)
Traverses the given source and target sequences and makes appropriate
        calls to :method:`traverse_one`.

        Algorithm:
        1) Build a map target item ID -> target data item from the target
           sequence;
        2) For each source data item in the source sequence check if it
           has a not-None ID; if yes, remove the corresponding target from the
           map generated in step 1) and use as target data item for the
           source data item; if no, use `None` as target data item;
        3) For the remaining items in the target map from 1), call
           :method:`traverse_one` passing `None` as source (REMOVE);
        4) For all source/target data item pairs generated in 2, call
           :method:`traverse_one` (ADD or UPDATE depending on whether target
           item is `None`).

        :param source_sequence: iterable of source data proxies
        :type source_sequence: iterator yielding instances of
                               `DataTraversalProxy` or None
        :param target_sequence: iterable of target data proxies
        :type target_sequence: iterator yielding instances of
                               `DataTraversalProxy` or None