def rename(self, names, prefix):
        """
        Rename the Attributes' names, prefixes, or both. If names or prefix
        evaluates to None, the old version is used.
        Resulting names must be unambiguous.
        :param names: A list of new names for each attribute or an empty list.
        :param prefix: A new prefix for the name or None
        """
        if names:
            if len(names) != len(self._contents):
                raise InputError('Attribute count mismatch.')
            if self.has_duplicates(names):
                raise InputError('Attributes are ambiguous.')
        else:
            # If the attributes are not renamed, but the relation / prefix is,
            # there is a risk of creating two or more attributes with the
            # same name and prefix.
            if prefix and self.has_duplicates(self.names):
                raise AttributeReferenceError('Attributes are ambiguous.')

        replacement = []
        for old, name in itertools.zip_longest(self._contents, names):
            new_name = name or old.name
            new_prefix = prefix or old.prefix
            replacement.append(Attribute(new_name, new_prefix))
        self._contents = replacement