<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def add_namespace_uri(self, ns_uri, prefix=None, schema_location=None):
 """Adds a new namespace to this set, optionally with a prefix and schema location URI. If the namespace already exists, the given prefix and schema location are merged with the existing entry: * If non-None, ``prefix`` is added to the set. The preferred prefix is not modified. * If a schema location is not already associated with the namespace, it is set to ``schema_location`` (if given). If the namespace doesn't already exist in this set (so a new one is being created) and a prefix is given, that prefix becomes preferred. If not given, a preference as a default namespace is used. Args: ns_uri (str):
 The URI of the new namespace prefix (str):
 The desired prefix for the new namespace (optional) schema_location (str):
 The desired schema location for the new namespace (optional). Raises: DuplicatePrefixError: If a prefix is given which already maps to a different namespace ConflictingSchemaLocationError: If a schema location is given and the namespace already exists in this set with a different schema location. """

        assert ns_uri

        if ns_uri in self.__ns_uri_map:
            # We have a _NamespaceInfo object for this URI already.  So this
            # is a merge operation.
            #
            # We modify a copy of the real _NamespaceInfo so that we are
            # exception-safe: if something goes wrong, we don't end up with a
            # half-changed NamespaceSet.
            ni = self.__lookup_uri(ns_uri)
            new_ni = copy.deepcopy(ni)

            # Reconcile prefixes
            if prefix:
                self.__check_prefix_conflict(ni, prefix)
                new_ni.prefixes.add(prefix)

            self.__merge_schema_locations(new_ni, schema_location)

            # At this point, we have a legit new_ni object.  Now we update
            # the set, ensuring our invariants.  This should replace
            # all instances of the old ni in this set.
            for p in new_ni.prefixes:
                self.__prefix_map[p] = new_ni
            self.__ns_uri_map[new_ni.uri] = new_ni

        else:
            # A brand new namespace.  The incoming prefix should not exist at
            # all in the prefix map.
            if prefix:
                self.__check_prefix_conflict(ns_uri, prefix)

            ni = _NamespaceInfo(ns_uri, prefix, schema_location)
            self.__add_namespaceinfo(ni)