def process(self, containers):
        from maya import cmds
        from avalon.maya.pipeline import AVALON_CONTAINERS
        from avalon.tools import sceneinventory
        from reveries.maya import hierarchy, pipeline, lib
        from reveries.maya.vendor import sticker
        from reveries import REVERIES_ICONS

        if not self.consent():
            return

        dimmed_icon = REVERIES_ICONS + "/package-01-dimmed.png"

        for container in containers:
            if not self.is_compatible(container):
                continue

            node = container["objectName"]
            members = cmds.sets(node, query=True) or []

            reference_node = lib.get_highest_reference_node(members)
            if reference_node is not None:
                # Import Reference
                cmds.file(importReference=True, referenceNode=reference_node)

            namespace = container["namespace"]

            for child in hierarchy.get_sub_container_nodes(container):
                # Update sub-containers' namespace entry
                child_ns = cmds.getAttr(child + ".namespace")
                new_ns = child_ns[len(namespace):]
                cmds.setAttr(child + ".namespace", new_ns, type="string")
                # Add to root container
                cmds.sets(child, forceElement=AVALON_CONTAINERS)

            # Merge namespace to root
            cmds.namespace(removeNamespace=namespace,
                           mergeNamespaceWithRoot=True)

            # Update subset group icon
            group = pipeline.get_group_from_container(node)
            if group is not None:
                sticker.put(group, dimmed_icon)

            # Delete container
            cmds.delete(node)

        # Refresh GUI
        sceneinventory.app.window.refresh()

        # Update Icon
        sticker.reveal()
    def _get_reference_node(self, members):
        """Get the reference node from the container members
        Args:
            members: list of node names

        Returns:
            str: Reference node name.

        """
        from reveries.maya import lib

        # Collect the references without .placeHolderList[] attributes as
        # unique entries (objects only) and skipping the sharedReferenceNode.
        references = lib.get_reference_node(members)

        if not references:
            return None

        # Get highest reference node (least parents)
        highest = lib.get_highest_reference_node(references)

        return highest
    def process(self, containers):
        from maya import cmds
        from reveries.maya import lib, pipeline
        from avalon.tools import sceneinventory

        cached_document = dict()

        def get_document(id):
            if id in cached_document:
                doc = cached_document[id]
            else:
                doc = io.find_one({"_id": io.ObjectId(id)})
                cached_document[id] = doc
            return doc

        for container in containers:
            namespace = container["namespace"]
            filter = {"id": "pyblish.avalon.container", "namespace": namespace}
            if len(lib.lsAttrs(filter)) == 1:
                # Namespace is unique
                continue

            # Create new namespace
            asset = get_document(container["assetId"])
            asset_name = asset["name"]

            subset = get_document(container["subsetId"])
            if subset["schema"] == "avalon-core:subset-3.0":
                family = subset["data"]["families"][0]
            else:
                version = get_document(container["versionId"])
                family = version["data"]["families"][0]
            family_name = family.split(".")[-1]

            new_namespace = pipeline.unique_root_namespace(
                asset_name=asset_name,
                family_name=family_name,
            )

            CON = container["objectName"]
            members = cmds.ls(cmds.sets(CON, query=True, nodesOnly=True),
                              long=True)
            reference_node = lib.get_highest_reference_node(members)

            if reference_node:
                filename = cmds.referenceQuery(reference_node, filename=True)
                cmds.file(filename, edit=True, namespace=new_namespace)
            else:
                cmds.namespace(add=new_namespace)

            for node in members:
                if not cmds.objExists(node):
                    continue
                if cmds.referenceQuery(node, isNodeReferenced=True):
                    continue
                if cmds.lockNode(node, query=True)[0]:
                    continue

                new = "|".join(
                    p.replace(namespace[1:], new_namespace[1:], 1)
                    for p in node.split("|"))
                if node != new:
                    cmds.rename(node, new)

            cmds.setAttr(CON + ".namespace", new_namespace, type="string")
            container["namespace"] = new_namespace

        sceneinventory.app.window.refresh()