docs: def traverse_one(self, attribute, source, target, visitor):
          """
          :param source: source data proxy
          :type source: instance of `DataTraversalProxy` or None
          :param target: target data proxy
          :type target: instance of `DataTraversalProxy` or None
          """
          if __debug__:
              self.__log_traverse_one(self.__trv_path, attribute, source, target)
          prx = source or target
          rel_op = RELATION_OPERATIONS.check(source, target)
          if prx.do_traverse() \
             and (rel_op == prx.relation_operation or attribute is None):
              for attr in prx.get_relationship_attributes():
                  # Check cascade settings.
                  if not bool(attr.cascade & rel_op):
                      continue
                  if not source is None:
                      try:
                          attr_source = source.get_attribute_proxy(attr)
                      except AttributeError:
                          # If the source does not have the attribute set, we
                          # do nothing (as opposed to when the value is None).
                          continue
                  else:
                      attr_source = None
                  if not target is None:
                      attr_target = target.get_attribute_proxy(attr)
                  else:
                      attr_target = None
                  attr_rel_op = RELATION_OPERATIONS.check(attr_source,
                                                          attr_target)
                  if attr_rel_op == RELATION_OPERATIONS.ADD:
                      if rel_op == RELATION_OPERATIONS.ADD:
                          parent = source
                      else:
                          parent = target
                  elif attr_rel_op == RELATION_OPERATIONS.REMOVE:
                      parent = target
                  else: # UPDATE
                      parent = target
                  card = get_attribute_cardinality(attr)
                  if card == CARDINALITY_CONSTANTS.ONE:
                      if attr_source is None and attr_target is None:
                          # If both source and target have None values, there is
                          # nothing to do.
                          continue
                      if attr_rel_op == RELATION_OPERATIONS.ADD:
  #                        if not attr_source.get_id() is None:
  #                            # We only ADD new items.
  #                            continue
                          src_items = [attr_source]
                          tgt_items = None
                      elif attr_rel_op == RELATION_OPERATIONS.REMOVE:
                          src_items = None
                          tgt_items = [attr_target]
                      else: # UPDATE
                          src_items = [attr_source]
                          tgt_items = [attr_target]
                          src_id = attr_source.get_id()
                          tgt_id = attr_target.get_id()
                          if src_id != tgt_id:
                              if not src_id is None:
                                  # If the source ID is None, this is a replace
                                  # operation (ADD source, REMOVE target).
                                  src_target = attr_target.get_matching(src_id)
                                  if not src_target is None:
                                      tgt_items.append(src_target)
                  else:
                      src_items = attr_source
                      tgt_items = attr_target
                  self.__trv_path.push(parent, (source, target), attr, rel_op)
                  self.traverse_many(attr, src_items, tgt_items, visitor)
                  self.__trv_path.pop() # path.pop()
          visitor.visit(self.__trv_path, attribute, source, target)